| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 1 | //===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 4ee451d | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // This file implements the AsmPrinter class. | 
 | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
| Evan Cheng | 932f022 | 2006-03-03 02:04:29 +0000 | [diff] [blame] | 14 | #include "llvm/CodeGen/AsmPrinter.h" | 
| Evan Cheng | 246ae0d | 2006-03-01 22:18:09 +0000 | [diff] [blame] | 15 | #include "llvm/Assembly/Writer.h" | 
| Nate Begeman | 8cfa57b | 2005-12-06 06:18:55 +0000 | [diff] [blame] | 16 | #include "llvm/DerivedTypes.h" | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 17 | #include "llvm/Constants.h" | 
| Chris Lattner | 450de39 | 2005-11-10 18:36:17 +0000 | [diff] [blame] | 18 | #include "llvm/Module.h" | 
| Gordon Henriksen | ce22477 | 2008-01-07 01:30:38 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/Collector.h" | 
 | 20 | #include "llvm/CodeGen/CollectorMetadata.h" | 
| Chris Lattner | 3b4fd32 | 2005-11-21 08:25:09 +0000 | [diff] [blame] | 21 | #include "llvm/CodeGen/MachineConstantPool.h" | 
| Nate Begeman | 37efe67 | 2006-04-22 18:53:45 +0000 | [diff] [blame] | 22 | #include "llvm/CodeGen/MachineJumpTableInfo.h" | 
| Chris Lattner | 84bc542 | 2007-12-31 04:13:23 +0000 | [diff] [blame] | 23 | #include "llvm/CodeGen/MachineModuleInfo.h" | 
| Jim Laskey | f1cdea1 | 2007-01-25 15:12:02 +0000 | [diff] [blame] | 24 | #include "llvm/Support/CommandLine.h" | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 25 | #include "llvm/Support/Mangler.h" | 
| Jim Laskey | cb6682f | 2005-08-17 19:34:49 +0000 | [diff] [blame] | 26 | #include "llvm/Support/MathExtras.h" | 
| Bill Wendling | bdc679d | 2006-11-29 00:39:47 +0000 | [diff] [blame] | 27 | #include "llvm/Support/Streams.h" | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 28 | #include "llvm/Target/TargetAsmInfo.h" | 
| Owen Anderson | 07000c6 | 2006-05-12 06:33:49 +0000 | [diff] [blame] | 29 | #include "llvm/Target/TargetData.h" | 
| Chris Lattner | 0336fdb | 2006-10-06 22:50:56 +0000 | [diff] [blame] | 30 | #include "llvm/Target/TargetLowering.h" | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 31 | #include "llvm/Target/TargetMachine.h" | 
| Evan Cheng | cc41586 | 2007-11-09 01:32:10 +0000 | [diff] [blame] | 32 | #include "llvm/ADT/SmallPtrSet.h" | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 33 | #include <cerrno> | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 34 | using namespace llvm; | 
 | 35 |  | 
| Jim Laskey | f1cdea1 | 2007-01-25 15:12:02 +0000 | [diff] [blame] | 36 | static cl::opt<bool> | 
 | 37 | AsmVerbose("asm-verbose", cl::Hidden, cl::desc("Add comments to directives.")); | 
 | 38 |  | 
| Devang Patel | 1997473 | 2007-05-03 01:11:54 +0000 | [diff] [blame] | 39 | char AsmPrinter::ID = 0; | 
| Jim Laskey | a0f3d17 | 2006-09-07 22:06:40 +0000 | [diff] [blame] | 40 | AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm, | 
 | 41 |                        const TargetAsmInfo *T) | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 42 |   : MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o), TM(tm), TAI(T) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 43 | {} | 
| Chris Lattner | ed13893 | 2005-12-13 06:32:10 +0000 | [diff] [blame] | 44 |  | 
| Chris Lattner | 52f0670 | 2006-10-05 02:42:47 +0000 | [diff] [blame] | 45 | std::string AsmPrinter::getSectionForFunction(const Function &F) const { | 
 | 46 |   return TAI->getTextSection(); | 
 | 47 | } | 
 | 48 |  | 
| Chris Lattner | ed13893 | 2005-12-13 06:32:10 +0000 | [diff] [blame] | 49 |  | 
| Chris Lattner | 4632d7a | 2006-05-09 04:59:56 +0000 | [diff] [blame] | 50 | /// SwitchToTextSection - Switch to the specified text section of the executable | 
 | 51 | /// if we are not already in it! | 
| Chris Lattner | ac28fbd | 2005-11-21 07:06:27 +0000 | [diff] [blame] | 52 | /// | 
| Chris Lattner | 4632d7a | 2006-05-09 04:59:56 +0000 | [diff] [blame] | 53 | void AsmPrinter::SwitchToTextSection(const char *NewSection, | 
 | 54 |                                      const GlobalValue *GV) { | 
| Chris Lattner | ac28fbd | 2005-11-21 07:06:27 +0000 | [diff] [blame] | 55 |   std::string NS; | 
| Chris Lattner | a7090ae | 2006-05-09 05:24:50 +0000 | [diff] [blame] | 56 |   if (GV && GV->hasSection()) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 57 |     NS = TAI->getSwitchToSectionDirective() + GV->getSection(); | 
| Chris Lattner | a7090ae | 2006-05-09 05:24:50 +0000 | [diff] [blame] | 58 |   else | 
 | 59 |     NS = NewSection; | 
 | 60 |    | 
 | 61 |   // If we're already in this section, we're done. | 
 | 62 |   if (CurrentSection == NS) return; | 
| Jeff Cohen | 51b776d | 2006-05-02 03:58:45 +0000 | [diff] [blame] | 63 |  | 
| Chris Lattner | 7faec9b | 2006-05-09 05:33:48 +0000 | [diff] [blame] | 64 |   // Close the current section, if applicable. | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 65 |   if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) | 
 | 66 |     O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << "\n"; | 
| Jeff Cohen | 51b776d | 2006-05-02 03:58:45 +0000 | [diff] [blame] | 67 |  | 
| Chris Lattner | 7faec9b | 2006-05-09 05:33:48 +0000 | [diff] [blame] | 68 |   CurrentSection = NS; | 
 | 69 |  | 
 | 70 |   if (!CurrentSection.empty()) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 71 |     O << CurrentSection << TAI->getTextSectionStartSuffix() << '\n'; | 
| Chris Lattner | ac28fbd | 2005-11-21 07:06:27 +0000 | [diff] [blame] | 72 | } | 
 | 73 |  | 
| Nate Begeman | 2f1ae88 | 2006-07-27 01:13:04 +0000 | [diff] [blame] | 74 | /// SwitchToDataSection - Switch to the specified data section of the executable | 
| Chris Lattner | 4632d7a | 2006-05-09 04:59:56 +0000 | [diff] [blame] | 75 | /// if we are not already in it! | 
 | 76 | /// | 
 | 77 | void AsmPrinter::SwitchToDataSection(const char *NewSection, | 
 | 78 |                                      const GlobalValue *GV) { | 
 | 79 |   std::string NS; | 
| Chris Lattner | b81cb61 | 2006-05-09 05:23:12 +0000 | [diff] [blame] | 80 |   if (GV && GV->hasSection()) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 81 |     NS = TAI->getSwitchToSectionDirective() + GV->getSection(); | 
| Chris Lattner | b81cb61 | 2006-05-09 05:23:12 +0000 | [diff] [blame] | 82 |   else | 
 | 83 |     NS = NewSection; | 
| Chris Lattner | 4632d7a | 2006-05-09 04:59:56 +0000 | [diff] [blame] | 84 |    | 
| Chris Lattner | b81cb61 | 2006-05-09 05:23:12 +0000 | [diff] [blame] | 85 |   // If we're already in this section, we're done. | 
 | 86 |   if (CurrentSection == NS) return; | 
 | 87 |  | 
| Chris Lattner | 7faec9b | 2006-05-09 05:33:48 +0000 | [diff] [blame] | 88 |   // Close the current section, if applicable. | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 89 |   if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) | 
 | 90 |     O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << "\n"; | 
| Chris Lattner | 7faec9b | 2006-05-09 05:33:48 +0000 | [diff] [blame] | 91 |  | 
 | 92 |   CurrentSection = NS; | 
| Chris Lattner | 4632d7a | 2006-05-09 04:59:56 +0000 | [diff] [blame] | 93 |    | 
| Chris Lattner | 7faec9b | 2006-05-09 05:33:48 +0000 | [diff] [blame] | 94 |   if (!CurrentSection.empty()) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 95 |     O << CurrentSection << TAI->getDataSectionStartSuffix() << '\n'; | 
| Chris Lattner | 4632d7a | 2006-05-09 04:59:56 +0000 | [diff] [blame] | 96 | } | 
 | 97 |  | 
 | 98 |  | 
| Gordon Henriksen | ce22477 | 2008-01-07 01:30:38 +0000 | [diff] [blame] | 99 | void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { | 
 | 100 |   MachineFunctionPass::getAnalysisUsage(AU); | 
 | 101 |   AU.addRequired<CollectorModuleMetadata>(); | 
 | 102 | } | 
 | 103 |  | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 104 | bool AsmPrinter::doInitialization(Module &M) { | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 105 |   Mang = new Mangler(M, TAI->getGlobalPrefix()); | 
| Chris Lattner | 2c1b159 | 2006-01-23 23:47:53 +0000 | [diff] [blame] | 106 |    | 
| Gordon Henriksen | ce22477 | 2008-01-07 01:30:38 +0000 | [diff] [blame] | 107 |   CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>(); | 
 | 108 |   assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?"); | 
 | 109 |   for (CollectorModuleMetadata::iterator I = CMM->begin(), | 
 | 110 |                                          E = CMM->end(); I != E; ++I) | 
 | 111 |     (*I)->beginAssembly(O, *this, *TAI); | 
 | 112 |    | 
| Chris Lattner | 3e2fa7a | 2006-01-24 04:16:34 +0000 | [diff] [blame] | 113 |   if (!M.getModuleInlineAsm().empty()) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 114 |     O << TAI->getCommentString() << " Start of file scope inline assembly\n" | 
| Chris Lattner | 3e2fa7a | 2006-01-24 04:16:34 +0000 | [diff] [blame] | 115 |       << M.getModuleInlineAsm() | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 116 |       << "\n" << TAI->getCommentString() | 
 | 117 |       << " End of file scope inline assembly\n"; | 
| Chris Lattner | 2c1b159 | 2006-01-23 23:47:53 +0000 | [diff] [blame] | 118 |  | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 119 |   SwitchToDataSection("");   // Reset back to no section. | 
| Jim Laskey | b3e789a | 2006-01-26 20:21:46 +0000 | [diff] [blame] | 120 |    | 
| Evan Cheng | 4e3f5a4 | 2008-02-04 23:06:48 +0000 | [diff] [blame] | 121 |   MMI = getAnalysisToUpdate<MachineModuleInfo>(); | 
 | 122 |   if (MMI) MMI->AnalyzeModule(M); | 
| Jim Laskey | b3e789a | 2006-01-26 20:21:46 +0000 | [diff] [blame] | 123 |    | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 124 |   return false; | 
 | 125 | } | 
 | 126 |  | 
 | 127 | bool AsmPrinter::doFinalization(Module &M) { | 
| Rafael Espindola | 15404d0 | 2006-12-18 03:37:18 +0000 | [diff] [blame] | 128 |   if (TAI->getWeakRefDirective()) { | 
| Anton Korobeynikov | 8b0a8c8 | 2007-04-25 14:27:10 +0000 | [diff] [blame] | 129 |     if (!ExtWeakSymbols.empty()) | 
| Rafael Espindola | 15404d0 | 2006-12-18 03:37:18 +0000 | [diff] [blame] | 130 |       SwitchToDataSection(""); | 
 | 131 |  | 
 | 132 |     for (std::set<const GlobalValue*>::iterator i = ExtWeakSymbols.begin(), | 
 | 133 |          e = ExtWeakSymbols.end(); i != e; ++i) { | 
 | 134 |       const GlobalValue *GV = *i; | 
 | 135 |       std::string Name = Mang->getValueName(GV); | 
 | 136 |       O << TAI->getWeakRefDirective() << Name << "\n"; | 
 | 137 |     } | 
 | 138 |   } | 
 | 139 |  | 
| Anton Korobeynikov | 8b0a8c8 | 2007-04-25 14:27:10 +0000 | [diff] [blame] | 140 |   if (TAI->getSetDirective()) { | 
| Anton Korobeynikov | a80e118 | 2007-04-28 13:45:00 +0000 | [diff] [blame] | 141 |     if (!M.alias_empty()) | 
| Anton Korobeynikov | 8b0a8c8 | 2007-04-25 14:27:10 +0000 | [diff] [blame] | 142 |       SwitchToTextSection(TAI->getTextSection()); | 
 | 143 |  | 
 | 144 |     O << "\n"; | 
 | 145 |     for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); | 
 | 146 |          I!=E; ++I) { | 
| Anton Korobeynikov | a80e118 | 2007-04-28 13:45:00 +0000 | [diff] [blame] | 147 |       std::string Name = Mang->getValueName(I); | 
 | 148 |       std::string Target; | 
| Anton Korobeynikov | 325be7c | 2007-09-06 17:21:48 +0000 | [diff] [blame] | 149 |  | 
 | 150 |       const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal()); | 
 | 151 |       Target = Mang->getValueName(GV); | 
| Anton Korobeynikov | a80e118 | 2007-04-28 13:45:00 +0000 | [diff] [blame] | 152 |        | 
| Anton Korobeynikov | 325be7c | 2007-09-06 17:21:48 +0000 | [diff] [blame] | 153 |       if (I->hasExternalLinkage() || !TAI->getWeakRefDirective()) | 
| Anton Korobeynikov | 8b0a8c8 | 2007-04-25 14:27:10 +0000 | [diff] [blame] | 154 |         O << "\t.globl\t" << Name << "\n"; | 
 | 155 |       else if (I->hasWeakLinkage()) | 
 | 156 |         O << TAI->getWeakRefDirective() << Name << "\n"; | 
 | 157 |       else if (!I->hasInternalLinkage()) | 
 | 158 |         assert(0 && "Invalid alias linkage"); | 
 | 159 |        | 
| Nick Lewycky | 33d4f77 | 2008-02-07 06:36:26 +0000 | [diff] [blame] | 160 |       O << TAI->getSetDirective() << ' ' << Name << ", " << Target << "\n"; | 
| Anton Korobeynikov | 325be7c | 2007-09-06 17:21:48 +0000 | [diff] [blame] | 161 |  | 
 | 162 |       // If the aliasee has external weak linkage it can be referenced only by | 
 | 163 |       // alias itself. In this case it can be not in ExtWeakSymbols list. Emit | 
 | 164 |       // weak reference in such case. | 
 | 165 |       if (GV->hasExternalWeakLinkage()) | 
 | 166 |         if (TAI->getWeakRefDirective()) | 
 | 167 |           O << TAI->getWeakRefDirective() << Target << "\n"; | 
 | 168 |         else | 
 | 169 |           O << "\t.globl\t" << Target << "\n"; | 
| Anton Korobeynikov | 8b0a8c8 | 2007-04-25 14:27:10 +0000 | [diff] [blame] | 170 |     } | 
 | 171 |   } | 
 | 172 |  | 
| Gordon Henriksen | ce22477 | 2008-01-07 01:30:38 +0000 | [diff] [blame] | 173 |   CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>(); | 
 | 174 |   assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?"); | 
 | 175 |   for (CollectorModuleMetadata::iterator I = CMM->end(), | 
 | 176 |                                          E = CMM->begin(); I != E; ) | 
 | 177 |     (*--I)->finishAssembly(O, *this, *TAI); | 
 | 178 |  | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 179 |   delete Mang; Mang = 0; | 
 | 180 |   return false; | 
 | 181 | } | 
 | 182 |  | 
| Bill Wendling | ce61328 | 2007-09-18 09:10:16 +0000 | [diff] [blame] | 183 | std::string AsmPrinter::getCurrentFunctionEHName(const MachineFunction *MF) { | 
| Bill Wendling | 6e19896 | 2007-09-18 01:47:22 +0000 | [diff] [blame] | 184 |   assert(MF && "No machine function?"); | 
| Bill Wendling | 5f19cf5 | 2007-09-18 05:03:44 +0000 | [diff] [blame] | 185 |   return Mang->makeNameProper(MF->getFunction()->getName() + ".eh", | 
 | 186 |                               TAI->getGlobalPrefix()); | 
| Bill Wendling | 6e19896 | 2007-09-18 01:47:22 +0000 | [diff] [blame] | 187 | } | 
 | 188 |  | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 189 | void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 190 |   // What's my mangled name? | 
| Chris Lattner | 450de39 | 2005-11-10 18:36:17 +0000 | [diff] [blame] | 191 |   CurrentFnName = Mang->getValueName(MF.getFunction()); | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 192 |   IncrementFunctionNumber(); | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 193 | } | 
 | 194 |  | 
| Chris Lattner | 3b4fd32 | 2005-11-21 08:25:09 +0000 | [diff] [blame] | 195 | /// EmitConstantPool - Print to the current output stream assembly | 
 | 196 | /// representations of the constants in the constant pool MCP. This is | 
 | 197 | /// used to print out constants which have been "spilled to memory" by | 
 | 198 | /// the code generator. | 
 | 199 | /// | 
 | 200 | void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { | 
| Chris Lattner | fa77d43 | 2006-02-09 04:22:52 +0000 | [diff] [blame] | 201 |   const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); | 
| Chris Lattner | 3b4fd32 | 2005-11-21 08:25:09 +0000 | [diff] [blame] | 202 |   if (CP.empty()) return; | 
| Evan Cheng | 2d2cec1 | 2006-06-29 00:26:09 +0000 | [diff] [blame] | 203 |  | 
 | 204 |   // Some targets require 4-, 8-, and 16- byte constant literals to be placed | 
 | 205 |   // in special sections. | 
 | 206 |   std::vector<std::pair<MachineConstantPoolEntry,unsigned> > FourByteCPs; | 
 | 207 |   std::vector<std::pair<MachineConstantPoolEntry,unsigned> > EightByteCPs; | 
 | 208 |   std::vector<std::pair<MachineConstantPoolEntry,unsigned> > SixteenByteCPs; | 
 | 209 |   std::vector<std::pair<MachineConstantPoolEntry,unsigned> > OtherCPs; | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 210 |   std::vector<std::pair<MachineConstantPoolEntry,unsigned> > TargetCPs; | 
| Chris Lattner | 3b4fd32 | 2005-11-21 08:25:09 +0000 | [diff] [blame] | 211 |   for (unsigned i = 0, e = CP.size(); i != e; ++i) { | 
| Evan Cheng | 2d2cec1 | 2006-06-29 00:26:09 +0000 | [diff] [blame] | 212 |     MachineConstantPoolEntry CPE = CP[i]; | 
| Evan Cheng | d5a99d7 | 2006-09-14 07:35:00 +0000 | [diff] [blame] | 213 |     const Type *Ty = CPE.getType(); | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 214 |     if (TAI->getFourByteConstantSection() && | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 215 |         TM.getTargetData()->getABITypeSize(Ty) == 4) | 
| Evan Cheng | 2d2cec1 | 2006-06-29 00:26:09 +0000 | [diff] [blame] | 216 |       FourByteCPs.push_back(std::make_pair(CPE, i)); | 
| Evan Cheng | 61c958e | 2006-09-07 18:50:20 +0000 | [diff] [blame] | 217 |     else if (TAI->getEightByteConstantSection() && | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 218 |              TM.getTargetData()->getABITypeSize(Ty) == 8) | 
| Evan Cheng | 2d2cec1 | 2006-06-29 00:26:09 +0000 | [diff] [blame] | 219 |       EightByteCPs.push_back(std::make_pair(CPE, i)); | 
| Evan Cheng | 61c958e | 2006-09-07 18:50:20 +0000 | [diff] [blame] | 220 |     else if (TAI->getSixteenByteConstantSection() && | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 221 |              TM.getTargetData()->getABITypeSize(Ty) == 16) | 
| Evan Cheng | 2d2cec1 | 2006-06-29 00:26:09 +0000 | [diff] [blame] | 222 |       SixteenByteCPs.push_back(std::make_pair(CPE, i)); | 
 | 223 |     else | 
 | 224 |       OtherCPs.push_back(std::make_pair(CPE, i)); | 
 | 225 |   } | 
 | 226 |  | 
 | 227 |   unsigned Alignment = MCP->getConstantPoolAlignment(); | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 228 |   EmitConstantPool(Alignment, TAI->getFourByteConstantSection(), FourByteCPs); | 
 | 229 |   EmitConstantPool(Alignment, TAI->getEightByteConstantSection(), EightByteCPs); | 
 | 230 |   EmitConstantPool(Alignment, TAI->getSixteenByteConstantSection(), | 
 | 231 |                    SixteenByteCPs); | 
 | 232 |   EmitConstantPool(Alignment, TAI->getConstantPoolSection(), OtherCPs); | 
| Evan Cheng | 2d2cec1 | 2006-06-29 00:26:09 +0000 | [diff] [blame] | 233 | } | 
 | 234 |  | 
 | 235 | void AsmPrinter::EmitConstantPool(unsigned Alignment, const char *Section, | 
 | 236 |                std::vector<std::pair<MachineConstantPoolEntry,unsigned> > &CP) { | 
 | 237 |   if (CP.empty()) return; | 
 | 238 |  | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 239 |   SwitchToDataSection(Section); | 
| Evan Cheng | 2d2cec1 | 2006-06-29 00:26:09 +0000 | [diff] [blame] | 240 |   EmitAlignment(Alignment); | 
 | 241 |   for (unsigned i = 0, e = CP.size(); i != e; ++i) { | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 242 |     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' | 
 | 243 |       << CP[i].second << ":\t\t\t\t\t" << TAI->getCommentString() << " "; | 
| Evan Cheng | d5a99d7 | 2006-09-14 07:35:00 +0000 | [diff] [blame] | 244 |     WriteTypeSymbolic(O, CP[i].first.getType(), 0) << '\n'; | 
 | 245 |     if (CP[i].first.isMachineConstantPoolEntry()) | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 246 |       EmitMachineConstantPoolValue(CP[i].first.Val.MachineCPVal); | 
| Evan Cheng | d5a99d7 | 2006-09-14 07:35:00 +0000 | [diff] [blame] | 247 |      else | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 248 |       EmitGlobalConstant(CP[i].first.Val.ConstVal); | 
| Chris Lattner | 3029f92 | 2006-02-09 04:46:04 +0000 | [diff] [blame] | 249 |     if (i != e-1) { | 
| Evan Cheng | d5a99d7 | 2006-09-14 07:35:00 +0000 | [diff] [blame] | 250 |       const Type *Ty = CP[i].first.getType(); | 
| Evan Cheng | 2d2cec1 | 2006-06-29 00:26:09 +0000 | [diff] [blame] | 251 |       unsigned EntSize = | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 252 |         TM.getTargetData()->getABITypeSize(Ty); | 
| Evan Cheng | d5a99d7 | 2006-09-14 07:35:00 +0000 | [diff] [blame] | 253 |       unsigned ValEnd = CP[i].first.getOffset() + EntSize; | 
| Chris Lattner | 3029f92 | 2006-02-09 04:46:04 +0000 | [diff] [blame] | 254 |       // Emit inter-object padding for alignment. | 
| Evan Cheng | d5a99d7 | 2006-09-14 07:35:00 +0000 | [diff] [blame] | 255 |       EmitZeros(CP[i+1].first.getOffset()-ValEnd); | 
| Chris Lattner | 3029f92 | 2006-02-09 04:46:04 +0000 | [diff] [blame] | 256 |     } | 
| Chris Lattner | 3b4fd32 | 2005-11-21 08:25:09 +0000 | [diff] [blame] | 257 |   } | 
 | 258 | } | 
 | 259 |  | 
| Nate Begeman | 37efe67 | 2006-04-22 18:53:45 +0000 | [diff] [blame] | 260 | /// EmitJumpTableInfo - Print assembly representations of the jump tables used | 
 | 261 | /// by the current function to the current output stream.   | 
 | 262 | /// | 
| Chris Lattner | 1da31ee | 2006-10-05 03:01:21 +0000 | [diff] [blame] | 263 | void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, | 
 | 264 |                                    MachineFunction &MF) { | 
| Nate Begeman | 37efe67 | 2006-04-22 18:53:45 +0000 | [diff] [blame] | 265 |   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); | 
 | 266 |   if (JT.empty()) return; | 
| Anton Korobeynikov | 9de1934 | 2007-11-14 09:18:41 +0000 | [diff] [blame] | 267 |  | 
| Jim Laskey | acd80ac | 2006-12-14 19:17:33 +0000 | [diff] [blame] | 268 |   bool IsPic = TM.getRelocationModel() == Reloc::PIC_; | 
| Nate Begeman | 4d9bbdc | 2006-07-27 16:46:58 +0000 | [diff] [blame] | 269 |    | 
| Nate Begeman | 2f1ae88 | 2006-07-27 01:13:04 +0000 | [diff] [blame] | 270 |   // Pick the directive to use to print the jump table entries, and switch to  | 
 | 271 |   // the appropriate section. | 
| Jim Laskey | acd80ac | 2006-12-14 19:17:33 +0000 | [diff] [blame] | 272 |   TargetLowering *LoweringInfo = TM.getTargetLowering(); | 
| Anton Korobeynikov | 24287dd | 2006-12-19 21:04:20 +0000 | [diff] [blame] | 273 |  | 
 | 274 |   const char* JumpTableDataSection = TAI->getJumpTableDataSection();   | 
 | 275 |   if ((IsPic && !(LoweringInfo && LoweringInfo->usesGlobalOffsetTable())) || | 
 | 276 |      !JumpTableDataSection) { | 
| Jim Laskey | acd80ac | 2006-12-14 19:17:33 +0000 | [diff] [blame] | 277 |     // In PIC mode, we need to emit the jump table to the same section as the | 
 | 278 |     // function body itself, otherwise the label differences won't make sense. | 
| Anton Korobeynikov | 24287dd | 2006-12-19 21:04:20 +0000 | [diff] [blame] | 279 |     // We should also do if the section name is NULL. | 
| Jim Laskey | acd80ac | 2006-12-14 19:17:33 +0000 | [diff] [blame] | 280 |     const Function *F = MF.getFunction(); | 
 | 281 |     SwitchToTextSection(getSectionForFunction(*F).c_str(), F); | 
| Nate Begeman | 2f1ae88 | 2006-07-27 01:13:04 +0000 | [diff] [blame] | 282 |   } else { | 
| Anton Korobeynikov | 24287dd | 2006-12-19 21:04:20 +0000 | [diff] [blame] | 283 |     SwitchToDataSection(JumpTableDataSection); | 
| Nate Begeman | 2f1ae88 | 2006-07-27 01:13:04 +0000 | [diff] [blame] | 284 |   } | 
| Jim Laskey | acd80ac | 2006-12-14 19:17:33 +0000 | [diff] [blame] | 285 |    | 
 | 286 |   EmitAlignment(Log2_32(MJTI->getAlignment())); | 
| Chris Lattner | 0c4e678 | 2006-07-15 01:34:12 +0000 | [diff] [blame] | 287 |    | 
| Nate Begeman | 37efe67 | 2006-04-22 18:53:45 +0000 | [diff] [blame] | 288 |   for (unsigned i = 0, e = JT.size(); i != e; ++i) { | 
| Nate Begeman | 52a51e38 | 2006-08-12 21:29:52 +0000 | [diff] [blame] | 289 |     const std::vector<MachineBasicBlock*> &JTBBs = JT[i].MBBs; | 
| Chris Lattner | 0737188 | 2006-10-28 18:10:06 +0000 | [diff] [blame] | 290 |      | 
 | 291 |     // If this jump table was deleted, ignore it.  | 
 | 292 |     if (JTBBs.empty()) continue; | 
| Nate Begeman | 52a51e38 | 2006-08-12 21:29:52 +0000 | [diff] [blame] | 293 |  | 
 | 294 |     // For PIC codegen, if possible we want to use the SetDirective to reduce | 
 | 295 |     // the number of relocations the assembler will generate for the jump table. | 
 | 296 |     // Set directives are all printed before the jump table itself. | 
| Evan Cheng | cc41586 | 2007-11-09 01:32:10 +0000 | [diff] [blame] | 297 |     SmallPtrSet<MachineBasicBlock*, 16> EmittedSets; | 
| Jim Laskey | acd80ac | 2006-12-14 19:17:33 +0000 | [diff] [blame] | 298 |     if (TAI->getSetDirective() && IsPic) | 
| Nate Begeman | 52a51e38 | 2006-08-12 21:29:52 +0000 | [diff] [blame] | 299 |       for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) | 
| Evan Cheng | cc41586 | 2007-11-09 01:32:10 +0000 | [diff] [blame] | 300 |         if (EmittedSets.insert(JTBBs[ii])) | 
 | 301 |           printPICJumpTableSetLabel(i, JTBBs[ii]); | 
| Nate Begeman | 52a51e38 | 2006-08-12 21:29:52 +0000 | [diff] [blame] | 302 |      | 
| Chris Lattner | 393a8ee | 2007-01-18 01:12:56 +0000 | [diff] [blame] | 303 |     // On some targets (e.g. darwin) we want to emit two consequtive labels | 
 | 304 |     // before each jump table.  The first label is never referenced, but tells | 
 | 305 |     // the assembler and linker the extents of the jump table object.  The | 
 | 306 |     // second label is actually referenced by the code. | 
 | 307 |     if (const char *JTLabelPrefix = TAI->getJumpTableSpecialLabelPrefix()) | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 308 |       O << JTLabelPrefix << "JTI" << getFunctionNumber() << '_' << i << ":\n"; | 
| Chris Lattner | 393a8ee | 2007-01-18 01:12:56 +0000 | [diff] [blame] | 309 |      | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 310 |     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()  | 
 | 311 |       << '_' << i << ":\n"; | 
| Nate Begeman | 52a51e38 | 2006-08-12 21:29:52 +0000 | [diff] [blame] | 312 |      | 
| Nate Begeman | 37efe67 | 2006-04-22 18:53:45 +0000 | [diff] [blame] | 313 |     for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { | 
| Anton Korobeynikov | 9de1934 | 2007-11-14 09:18:41 +0000 | [diff] [blame] | 314 |       printPICJumpTableEntry(MJTI, JTBBs[ii], i); | 
| Nate Begeman | 37efe67 | 2006-04-22 18:53:45 +0000 | [diff] [blame] | 315 |       O << '\n'; | 
 | 316 |     } | 
 | 317 |   } | 
 | 318 | } | 
 | 319 |  | 
| Anton Korobeynikov | 9de1934 | 2007-11-14 09:18:41 +0000 | [diff] [blame] | 320 | void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, | 
 | 321 |                                         const MachineBasicBlock *MBB, | 
 | 322 |                                         unsigned uid)  const { | 
 | 323 |   bool IsPic = TM.getRelocationModel() == Reloc::PIC_; | 
 | 324 |    | 
 | 325 |   // Use JumpTableDirective otherwise honor the entry size from the jump table | 
 | 326 |   // info. | 
 | 327 |   const char *JTEntryDirective = TAI->getJumpTableDirective(); | 
 | 328 |   bool HadJTEntryDirective = JTEntryDirective != NULL; | 
 | 329 |   if (!HadJTEntryDirective) { | 
 | 330 |     JTEntryDirective = MJTI->getEntrySize() == 4 ? | 
 | 331 |       TAI->getData32bitsDirective() : TAI->getData64bitsDirective(); | 
 | 332 |   } | 
 | 333 |  | 
 | 334 |   O << JTEntryDirective << ' '; | 
 | 335 |  | 
 | 336 |   // If we have emitted set directives for the jump table entries, print  | 
 | 337 |   // them rather than the entries themselves.  If we're emitting PIC, then | 
 | 338 |   // emit the table entries as differences between two text section labels. | 
 | 339 |   // If we're emitting non-PIC code, then emit the entries as direct | 
 | 340 |   // references to the target basic blocks. | 
 | 341 |   if (IsPic) { | 
 | 342 |     if (TAI->getSetDirective()) { | 
 | 343 |       O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() | 
 | 344 |         << '_' << uid << "_set_" << MBB->getNumber(); | 
 | 345 |     } else { | 
 | 346 |       printBasicBlockLabel(MBB, false, false); | 
 | 347 |       // If the arch uses custom Jump Table directives, don't calc relative to | 
 | 348 |       // JT | 
 | 349 |       if (!HadJTEntryDirective)  | 
 | 350 |         O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" | 
 | 351 |           << getFunctionNumber() << '_' << uid; | 
 | 352 |     } | 
 | 353 |   } else { | 
 | 354 |     printBasicBlockLabel(MBB, false, false); | 
 | 355 |   } | 
 | 356 | } | 
 | 357 |  | 
 | 358 |  | 
| Chris Lattner | ed13893 | 2005-12-13 06:32:10 +0000 | [diff] [blame] | 359 | /// EmitSpecialLLVMGlobal - Check to see if the specified global is a | 
 | 360 | /// special global used by LLVM.  If so, emit it and return true, otherwise | 
 | 361 | /// do nothing and return false. | 
 | 362 | bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { | 
| Andrew Lenharth | b753a9b | 2007-08-22 19:33:11 +0000 | [diff] [blame] | 363 |   if (GV->getName() == "llvm.used") { | 
 | 364 |     if (TAI->getUsedDirective() != 0)    // No need to emit this at all. | 
 | 365 |       EmitLLVMUsedList(GV->getInitializer()); | 
 | 366 |     return true; | 
 | 367 |   } | 
 | 368 |  | 
| Jim Laskey | 7809811 | 2006-03-07 22:00:35 +0000 | [diff] [blame] | 369 |   // Ignore debug and non-emitted data. | 
 | 370 |   if (GV->getSection() == "llvm.metadata") return true; | 
 | 371 |    | 
 | 372 |   if (!GV->hasAppendingLinkage()) return false; | 
 | 373 |  | 
 | 374 |   assert(GV->hasInitializer() && "Not a special LLVM global!"); | 
| Chris Lattner | ed13893 | 2005-12-13 06:32:10 +0000 | [diff] [blame] | 375 |    | 
| Evan Cheng | 916d07c | 2007-06-04 20:39:18 +0000 | [diff] [blame] | 376 |   const TargetData *TD = TM.getTargetData(); | 
 | 377 |   unsigned Align = Log2_32(TD->getPointerPrefAlignment()); | 
| Chris Lattner | 5166b82 | 2006-01-12 19:17:23 +0000 | [diff] [blame] | 378 |   if (GV->getName() == "llvm.global_ctors" && GV->use_empty()) { | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 379 |     SwitchToDataSection(TAI->getStaticCtorsSection()); | 
| Evan Cheng | 916d07c | 2007-06-04 20:39:18 +0000 | [diff] [blame] | 380 |     EmitAlignment(Align, 0); | 
| Chris Lattner | ed13893 | 2005-12-13 06:32:10 +0000 | [diff] [blame] | 381 |     EmitXXStructorList(GV->getInitializer()); | 
 | 382 |     return true; | 
 | 383 |   }  | 
 | 384 |    | 
| Chris Lattner | 5166b82 | 2006-01-12 19:17:23 +0000 | [diff] [blame] | 385 |   if (GV->getName() == "llvm.global_dtors" && GV->use_empty()) { | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 386 |     SwitchToDataSection(TAI->getStaticDtorsSection()); | 
| Evan Cheng | 916d07c | 2007-06-04 20:39:18 +0000 | [diff] [blame] | 387 |     EmitAlignment(Align, 0); | 
| Chris Lattner | ed13893 | 2005-12-13 06:32:10 +0000 | [diff] [blame] | 388 |     EmitXXStructorList(GV->getInitializer()); | 
 | 389 |     return true; | 
 | 390 |   } | 
 | 391 |    | 
 | 392 |   return false; | 
 | 393 | } | 
 | 394 |  | 
| Chris Lattner | cb05af8 | 2006-09-26 03:38:18 +0000 | [diff] [blame] | 395 | /// EmitLLVMUsedList - For targets that define a TAI::UsedDirective, mark each | 
 | 396 | /// global in the specified llvm.used list as being used with this directive. | 
 | 397 | void AsmPrinter::EmitLLVMUsedList(Constant *List) { | 
 | 398 |   const char *Directive = TAI->getUsedDirective(); | 
 | 399 |  | 
 | 400 |   // Should be an array of 'sbyte*'. | 
 | 401 |   ConstantArray *InitList = dyn_cast<ConstantArray>(List); | 
 | 402 |   if (InitList == 0) return; | 
 | 403 |    | 
 | 404 |   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { | 
 | 405 |     O << Directive; | 
 | 406 |     EmitConstantValueOnly(InitList->getOperand(i)); | 
 | 407 |     O << "\n"; | 
 | 408 |   } | 
 | 409 | } | 
 | 410 |  | 
| Chris Lattner | ed13893 | 2005-12-13 06:32:10 +0000 | [diff] [blame] | 411 | /// EmitXXStructorList - Emit the ctor or dtor list.  This just prints out the  | 
 | 412 | /// function pointers, ignoring the init priority. | 
 | 413 | void AsmPrinter::EmitXXStructorList(Constant *List) { | 
 | 414 |   // Should be an array of '{ int, void ()* }' structs.  The first value is the | 
 | 415 |   // init priority, which we ignore. | 
 | 416 |   if (!isa<ConstantArray>(List)) return; | 
 | 417 |   ConstantArray *InitList = cast<ConstantArray>(List); | 
 | 418 |   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) | 
 | 419 |     if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){ | 
 | 420 |       if (CS->getNumOperands() != 2) return;  // Not array of 2-element structs. | 
| Chris Lattner | 8de324b | 2005-12-21 01:17:37 +0000 | [diff] [blame] | 421 |  | 
 | 422 |       if (CS->getOperand(1)->isNullValue()) | 
 | 423 |         return;  // Found a null terminator, exit printing. | 
 | 424 |       // Emit the function pointer. | 
| Chris Lattner | ed13893 | 2005-12-13 06:32:10 +0000 | [diff] [blame] | 425 |       EmitGlobalConstant(CS->getOperand(1)); | 
 | 426 |     } | 
 | 427 | } | 
| Chris Lattner | 3b4fd32 | 2005-11-21 08:25:09 +0000 | [diff] [blame] | 428 |  | 
| Jim Laskey | a1a19f8 | 2006-10-17 13:41:07 +0000 | [diff] [blame] | 429 | /// getGlobalLinkName - Returns the asm/link name of of the specified | 
 | 430 | /// global variable.  Should be overridden by each target asm printer to | 
 | 431 | /// generate the appropriate value. | 
| Jim Laskey | 99e41ee | 2006-10-17 17:17:24 +0000 | [diff] [blame] | 432 | const std::string AsmPrinter::getGlobalLinkName(const GlobalVariable *GV) const{ | 
 | 433 |   std::string LinkName; | 
| Jim Laskey | 0374248 | 2006-11-20 20:29:06 +0000 | [diff] [blame] | 434 |    | 
 | 435 |   if (isa<Function>(GV)) { | 
 | 436 |     LinkName += TAI->getFunctionAddrPrefix(); | 
 | 437 |     LinkName += Mang->getValueName(GV); | 
 | 438 |     LinkName += TAI->getFunctionAddrSuffix(); | 
 | 439 |   } else { | 
 | 440 |     LinkName += TAI->getGlobalVarAddrPrefix(); | 
 | 441 |     LinkName += Mang->getValueName(GV); | 
 | 442 |     LinkName += TAI->getGlobalVarAddrSuffix(); | 
 | 443 |   }   | 
 | 444 |    | 
| Jim Laskey | 99e41ee | 2006-10-17 17:17:24 +0000 | [diff] [blame] | 445 |   return LinkName; | 
| Jim Laskey | a1a19f8 | 2006-10-17 13:41:07 +0000 | [diff] [blame] | 446 | } | 
 | 447 |  | 
| Jim Laskey | bda9b0e | 2007-02-21 22:47:38 +0000 | [diff] [blame] | 448 | /// EmitExternalGlobal - Emit the external reference to a global variable. | 
 | 449 | /// Should be overridden if an indirect reference should be used. | 
 | 450 | void AsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) { | 
 | 451 |   O << getGlobalLinkName(GV); | 
 | 452 | } | 
 | 453 |  | 
 | 454 |  | 
 | 455 |  | 
| Jim Laskey | f1cdea1 | 2007-01-25 15:12:02 +0000 | [diff] [blame] | 456 | //===----------------------------------------------------------------------===// | 
 | 457 | /// LEB 128 number encoding. | 
 | 458 |  | 
 | 459 | /// PrintULEB128 - Print a series of hexidecimal values (separated by commas) | 
 | 460 | /// representing an unsigned leb128 value. | 
 | 461 | void AsmPrinter::PrintULEB128(unsigned Value) const { | 
 | 462 |   do { | 
 | 463 |     unsigned Byte = Value & 0x7f; | 
 | 464 |     Value >>= 7; | 
 | 465 |     if (Value) Byte |= 0x80; | 
 | 466 |     O << "0x" << std::hex << Byte << std::dec; | 
 | 467 |     if (Value) O << ", "; | 
 | 468 |   } while (Value); | 
 | 469 | } | 
 | 470 |  | 
 | 471 | /// SizeULEB128 - Compute the number of bytes required for an unsigned leb128 | 
 | 472 | /// value. | 
 | 473 | unsigned AsmPrinter::SizeULEB128(unsigned Value) { | 
 | 474 |   unsigned Size = 0; | 
 | 475 |   do { | 
 | 476 |     Value >>= 7; | 
 | 477 |     Size += sizeof(int8_t); | 
 | 478 |   } while (Value); | 
 | 479 |   return Size; | 
 | 480 | } | 
 | 481 |  | 
 | 482 | /// PrintSLEB128 - Print a series of hexidecimal values (separated by commas) | 
 | 483 | /// representing a signed leb128 value. | 
 | 484 | void AsmPrinter::PrintSLEB128(int Value) const { | 
 | 485 |   int Sign = Value >> (8 * sizeof(Value) - 1); | 
 | 486 |   bool IsMore; | 
 | 487 |    | 
 | 488 |   do { | 
 | 489 |     unsigned Byte = Value & 0x7f; | 
 | 490 |     Value >>= 7; | 
 | 491 |     IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; | 
 | 492 |     if (IsMore) Byte |= 0x80; | 
 | 493 |     O << "0x" << std::hex << Byte << std::dec; | 
 | 494 |     if (IsMore) O << ", "; | 
 | 495 |   } while (IsMore); | 
 | 496 | } | 
 | 497 |  | 
 | 498 | /// SizeSLEB128 - Compute the number of bytes required for a signed leb128 | 
 | 499 | /// value. | 
 | 500 | unsigned AsmPrinter::SizeSLEB128(int Value) { | 
 | 501 |   unsigned Size = 0; | 
 | 502 |   int Sign = Value >> (8 * sizeof(Value) - 1); | 
 | 503 |   bool IsMore; | 
 | 504 |    | 
 | 505 |   do { | 
 | 506 |     unsigned Byte = Value & 0x7f; | 
 | 507 |     Value >>= 7; | 
 | 508 |     IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; | 
 | 509 |     Size += sizeof(int8_t); | 
 | 510 |   } while (IsMore); | 
 | 511 |   return Size; | 
 | 512 | } | 
 | 513 |  | 
 | 514 | //===--------------------------------------------------------------------===// | 
 | 515 | // Emission and print routines | 
 | 516 | // | 
 | 517 |  | 
 | 518 | /// PrintHex - Print a value as a hexidecimal value. | 
 | 519 | /// | 
 | 520 | void AsmPrinter::PrintHex(int Value) const {  | 
 | 521 |   O << "0x" << std::hex << Value << std::dec; | 
 | 522 | } | 
 | 523 |  | 
 | 524 | /// EOL - Print a newline character to asm stream.  If a comment is present | 
 | 525 | /// then it will be printed first.  Comments should not contain '\n'. | 
| Jim Laskey | bda9b0e | 2007-02-21 22:47:38 +0000 | [diff] [blame] | 526 | void AsmPrinter::EOL() const { | 
 | 527 |   O << "\n"; | 
 | 528 | } | 
| Jim Laskey | f1cdea1 | 2007-01-25 15:12:02 +0000 | [diff] [blame] | 529 | void AsmPrinter::EOL(const std::string &Comment) const { | 
 | 530 |   if (AsmVerbose && !Comment.empty()) { | 
 | 531 |     O << "\t" | 
 | 532 |       << TAI->getCommentString() | 
 | 533 |       << " " | 
 | 534 |       << Comment; | 
 | 535 |   } | 
 | 536 |   O << "\n"; | 
 | 537 | } | 
 | 538 |  | 
 | 539 | /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an | 
 | 540 | /// unsigned leb128 value. | 
 | 541 | void AsmPrinter::EmitULEB128Bytes(unsigned Value) const { | 
 | 542 |   if (TAI->hasLEB128()) { | 
 | 543 |     O << "\t.uleb128\t" | 
 | 544 |       << Value; | 
 | 545 |   } else { | 
 | 546 |     O << TAI->getData8bitsDirective(); | 
 | 547 |     PrintULEB128(Value); | 
 | 548 |   } | 
 | 549 | } | 
 | 550 |  | 
 | 551 | /// EmitSLEB128Bytes - print an assembler byte data directive to compose a | 
 | 552 | /// signed leb128 value. | 
 | 553 | void AsmPrinter::EmitSLEB128Bytes(int Value) const { | 
 | 554 |   if (TAI->hasLEB128()) { | 
 | 555 |     O << "\t.sleb128\t" | 
 | 556 |       << Value; | 
 | 557 |   } else { | 
 | 558 |     O << TAI->getData8bitsDirective(); | 
 | 559 |     PrintSLEB128(Value); | 
 | 560 |   } | 
 | 561 | } | 
 | 562 |  | 
 | 563 | /// EmitInt8 - Emit a byte directive and value. | 
 | 564 | /// | 
 | 565 | void AsmPrinter::EmitInt8(int Value) const { | 
 | 566 |   O << TAI->getData8bitsDirective(); | 
 | 567 |   PrintHex(Value & 0xFF); | 
 | 568 | } | 
 | 569 |  | 
 | 570 | /// EmitInt16 - Emit a short directive and value. | 
 | 571 | /// | 
 | 572 | void AsmPrinter::EmitInt16(int Value) const { | 
 | 573 |   O << TAI->getData16bitsDirective(); | 
 | 574 |   PrintHex(Value & 0xFFFF); | 
 | 575 | } | 
 | 576 |  | 
 | 577 | /// EmitInt32 - Emit a long directive and value. | 
 | 578 | /// | 
 | 579 | void AsmPrinter::EmitInt32(int Value) const { | 
 | 580 |   O << TAI->getData32bitsDirective(); | 
 | 581 |   PrintHex(Value); | 
 | 582 | } | 
 | 583 |  | 
 | 584 | /// EmitInt64 - Emit a long long directive and value. | 
 | 585 | /// | 
 | 586 | void AsmPrinter::EmitInt64(uint64_t Value) const { | 
 | 587 |   if (TAI->getData64bitsDirective()) { | 
 | 588 |     O << TAI->getData64bitsDirective(); | 
 | 589 |     PrintHex(Value); | 
 | 590 |   } else { | 
 | 591 |     if (TM.getTargetData()->isBigEndian()) { | 
 | 592 |       EmitInt32(unsigned(Value >> 32)); O << "\n"; | 
 | 593 |       EmitInt32(unsigned(Value)); | 
 | 594 |     } else { | 
 | 595 |       EmitInt32(unsigned(Value)); O << "\n"; | 
 | 596 |       EmitInt32(unsigned(Value >> 32)); | 
 | 597 |     } | 
 | 598 |   } | 
 | 599 | } | 
 | 600 |  | 
 | 601 | /// toOctal - Convert the low order bits of X into an octal digit. | 
 | 602 | /// | 
 | 603 | static inline char toOctal(int X) { | 
 | 604 |   return (X&7)+'0'; | 
 | 605 | } | 
 | 606 |  | 
 | 607 | /// printStringChar - Print a char, escaped if necessary. | 
 | 608 | /// | 
 | 609 | static void printStringChar(std::ostream &O, unsigned char C) { | 
 | 610 |   if (C == '"') { | 
 | 611 |     O << "\\\""; | 
 | 612 |   } else if (C == '\\') { | 
 | 613 |     O << "\\\\"; | 
 | 614 |   } else if (isprint(C)) { | 
 | 615 |     O << C; | 
 | 616 |   } else { | 
 | 617 |     switch(C) { | 
 | 618 |     case '\b': O << "\\b"; break; | 
 | 619 |     case '\f': O << "\\f"; break; | 
 | 620 |     case '\n': O << "\\n"; break; | 
 | 621 |     case '\r': O << "\\r"; break; | 
 | 622 |     case '\t': O << "\\t"; break; | 
 | 623 |     default: | 
 | 624 |       O << '\\'; | 
 | 625 |       O << toOctal(C >> 6); | 
 | 626 |       O << toOctal(C >> 3); | 
 | 627 |       O << toOctal(C >> 0); | 
 | 628 |       break; | 
 | 629 |     } | 
 | 630 |   } | 
 | 631 | } | 
 | 632 |  | 
 | 633 | /// EmitString - Emit a string with quotes and a null terminator. | 
 | 634 | /// Special characters are emitted properly. | 
 | 635 | /// \literal (Eg. '\t') \endliteral | 
 | 636 | void AsmPrinter::EmitString(const std::string &String) const { | 
| Anton Korobeynikov | fb269cf | 2007-03-06 19:25:02 +0000 | [diff] [blame] | 637 |   const char* AscizDirective = TAI->getAscizDirective(); | 
 | 638 |   if (AscizDirective) | 
 | 639 |     O << AscizDirective; | 
 | 640 |   else | 
 | 641 |     O << TAI->getAsciiDirective(); | 
 | 642 |   O << "\""; | 
| Jim Laskey | f1cdea1 | 2007-01-25 15:12:02 +0000 | [diff] [blame] | 643 |   for (unsigned i = 0, N = String.size(); i < N; ++i) { | 
 | 644 |     unsigned char C = String[i]; | 
 | 645 |     printStringChar(O, C); | 
 | 646 |   } | 
| Anton Korobeynikov | fb269cf | 2007-03-06 19:25:02 +0000 | [diff] [blame] | 647 |   if (AscizDirective) | 
 | 648 |     O << "\""; | 
 | 649 |   else | 
 | 650 |     O << "\\0\""; | 
| Jim Laskey | f1cdea1 | 2007-01-25 15:12:02 +0000 | [diff] [blame] | 651 | } | 
 | 652 |  | 
 | 653 |  | 
| Dan Gohman | 189f80d | 2007-09-24 20:58:13 +0000 | [diff] [blame] | 654 | /// EmitFile - Emit a .file directive. | 
 | 655 | void AsmPrinter::EmitFile(unsigned Number, const std::string &Name) const { | 
 | 656 |   O << "\t.file\t" << Number << " \""; | 
 | 657 |   for (unsigned i = 0, N = Name.size(); i < N; ++i) { | 
 | 658 |     unsigned char C = Name[i]; | 
 | 659 |     printStringChar(O, C); | 
 | 660 |   } | 
 | 661 |   O << "\""; | 
 | 662 | } | 
 | 663 |  | 
 | 664 |  | 
| Jim Laskey | f1cdea1 | 2007-01-25 15:12:02 +0000 | [diff] [blame] | 665 | //===----------------------------------------------------------------------===// | 
 | 666 |  | 
| Chris Lattner | 3a42053 | 2007-05-31 18:57:45 +0000 | [diff] [blame] | 667 | // EmitAlignment - Emit an alignment directive to the specified power of | 
 | 668 | // two boundary.  For example, if you pass in 3 here, you will get an 8 | 
 | 669 | // byte alignment.  If a global value is specified, and if that global has | 
 | 670 | // an explicit alignment requested, it will unconditionally override the | 
 | 671 | // alignment request.  However, if ForcedAlignBits is specified, this value | 
 | 672 | // has final say: the ultimate alignment will be the max of ForcedAlignBits | 
 | 673 | // and the alignment computed with NumBits and the global. | 
 | 674 | // | 
 | 675 | // The algorithm is: | 
 | 676 | //     Align = NumBits; | 
 | 677 | //     if (GV && GV->hasalignment) Align = GV->getalignment(); | 
 | 678 | //     Align = std::max(Align, ForcedAlignBits); | 
 | 679 | // | 
 | 680 | void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV, | 
| Evan Cheng | 73a259a | 2007-07-25 23:35:07 +0000 | [diff] [blame] | 681 |                                unsigned ForcedAlignBits, bool UseFillExpr, | 
 | 682 |                                unsigned FillValue) const { | 
| Dale Johannesen | 00d56b9 | 2007-04-23 23:33:31 +0000 | [diff] [blame] | 683 |   if (GV && GV->getAlignment()) | 
| Chris Lattner | 3a42053 | 2007-05-31 18:57:45 +0000 | [diff] [blame] | 684 |     NumBits = Log2_32(GV->getAlignment()); | 
 | 685 |   NumBits = std::max(NumBits, ForcedAlignBits); | 
 | 686 |    | 
| Chris Lattner | 2a21c6e | 2005-11-10 18:09:27 +0000 | [diff] [blame] | 687 |   if (NumBits == 0) return;   // No need to emit alignment. | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 688 |   if (TAI->getAlignmentIsInBytes()) NumBits = 1 << NumBits; | 
| Evan Cheng | 73a259a | 2007-07-25 23:35:07 +0000 | [diff] [blame] | 689 |   O << TAI->getAlignDirective() << NumBits; | 
 | 690 |   if (UseFillExpr) O << ",0x" << std::hex << FillValue << std::dec; | 
 | 691 |   O << "\n"; | 
| Chris Lattner | bfddc20 | 2004-08-17 19:14:29 +0000 | [diff] [blame] | 692 | } | 
 | 693 |  | 
| Jim Laskey | bda9b0e | 2007-02-21 22:47:38 +0000 | [diff] [blame] | 694 |      | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 695 | /// EmitZeros - Emit a block of zeros. | 
| Chris Lattner | 7d057a3 | 2004-08-17 21:38:40 +0000 | [diff] [blame] | 696 | /// | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 697 | void AsmPrinter::EmitZeros(uint64_t NumZeros) const { | 
| Chris Lattner | 7d057a3 | 2004-08-17 21:38:40 +0000 | [diff] [blame] | 698 |   if (NumZeros) { | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 699 |     if (TAI->getZeroDirective()) { | 
 | 700 |       O << TAI->getZeroDirective() << NumZeros; | 
 | 701 |       if (TAI->getZeroDirectiveSuffix()) | 
 | 702 |         O << TAI->getZeroDirectiveSuffix(); | 
| Jeff Cohen | c6a057b | 2006-05-02 03:46:13 +0000 | [diff] [blame] | 703 |       O << "\n"; | 
 | 704 |     } else { | 
| Chris Lattner | 7d057a3 | 2004-08-17 21:38:40 +0000 | [diff] [blame] | 705 |       for (; NumZeros; --NumZeros) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 706 |         O << TAI->getData8bitsDirective() << "0\n"; | 
| Chris Lattner | 7d057a3 | 2004-08-17 21:38:40 +0000 | [diff] [blame] | 707 |     } | 
 | 708 |   } | 
 | 709 | } | 
 | 710 |  | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 711 | // Print out the specified constant, without a storage class.  Only the | 
 | 712 | // constants valid in constant expressions can occur here. | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 713 | void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { | 
| Chris Lattner | bd1d382 | 2004-10-16 18:19:26 +0000 | [diff] [blame] | 714 |   if (CV->isNullValue() || isa<UndefValue>(CV)) | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 715 |     O << "0"; | 
| Zhou Sheng | 6b6b6ef | 2007-01-11 12:24:14 +0000 | [diff] [blame] | 716 |   else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { | 
| Chris Lattner | a875df3 | 2007-01-12 18:15:09 +0000 | [diff] [blame] | 717 |     O << CI->getZExtValue(); | 
| Reid Spencer | b83eb64 | 2006-10-20 07:07:24 +0000 | [diff] [blame] | 718 |   } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) { | 
| Duraid Madina | 855a519 | 2005-04-02 12:21:51 +0000 | [diff] [blame] | 719 |     // This is a constant address for a global variable or function. Use the | 
 | 720 |     // name of the variable or function as the address value, possibly | 
 | 721 |     // decorating it with GlobalVarAddrPrefix/Suffix or | 
 | 722 |     // FunctionAddrPrefix/Suffix (these all default to "" ) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 723 |     if (isa<Function>(GV)) { | 
 | 724 |       O << TAI->getFunctionAddrPrefix() | 
 | 725 |         << Mang->getValueName(GV) | 
 | 726 |         << TAI->getFunctionAddrSuffix(); | 
 | 727 |     } else { | 
 | 728 |       O << TAI->getGlobalVarAddrPrefix() | 
 | 729 |         << Mang->getValueName(GV) | 
 | 730 |         << TAI->getGlobalVarAddrSuffix(); | 
 | 731 |     } | 
| Duraid Madina | 855a519 | 2005-04-02 12:21:51 +0000 | [diff] [blame] | 732 |   } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { | 
| Owen Anderson | a69571c | 2006-05-03 01:29:57 +0000 | [diff] [blame] | 733 |     const TargetData *TD = TM.getTargetData(); | 
| Anton Korobeynikov | 13b7d3d | 2007-02-04 23:27:42 +0000 | [diff] [blame] | 734 |     unsigned Opcode = CE->getOpcode();     | 
 | 735 |     switch (Opcode) { | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 736 |     case Instruction::GetElementPtr: { | 
 | 737 |       // generate a symbolic expression for the byte address | 
 | 738 |       const Constant *ptrVal = CE->getOperand(0); | 
| Chris Lattner | 7f6b9d2 | 2007-02-10 20:31:59 +0000 | [diff] [blame] | 739 |       SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end()); | 
 | 740 |       if (int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0], | 
 | 741 |                                                 idxVec.size())) { | 
| Chris Lattner | 27e1921 | 2005-02-14 21:40:26 +0000 | [diff] [blame] | 742 |         if (Offset) | 
 | 743 |           O << "("; | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 744 |         EmitConstantValueOnly(ptrVal); | 
| Chris Lattner | 27e1921 | 2005-02-14 21:40:26 +0000 | [diff] [blame] | 745 |         if (Offset > 0) | 
 | 746 |           O << ") + " << Offset; | 
 | 747 |         else if (Offset < 0) | 
 | 748 |           O << ") - " << -Offset; | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 749 |       } else { | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 750 |         EmitConstantValueOnly(ptrVal); | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 751 |       } | 
 | 752 |       break; | 
 | 753 |     } | 
| Reid Spencer | 3da59db | 2006-11-27 01:05:10 +0000 | [diff] [blame] | 754 |     case Instruction::Trunc: | 
 | 755 |     case Instruction::ZExt: | 
 | 756 |     case Instruction::SExt: | 
 | 757 |     case Instruction::FPTrunc: | 
 | 758 |     case Instruction::FPExt: | 
 | 759 |     case Instruction::UIToFP: | 
 | 760 |     case Instruction::SIToFP: | 
 | 761 |     case Instruction::FPToUI: | 
 | 762 |     case Instruction::FPToSI: | 
 | 763 |       assert(0 && "FIXME: Don't yet support this kind of constant cast expr"); | 
 | 764 |       break; | 
| Chris Lattner | cb0a681 | 2006-12-12 05:14:13 +0000 | [diff] [blame] | 765 |     case Instruction::BitCast: | 
 | 766 |       return EmitConstantValueOnly(CE->getOperand(0)); | 
 | 767 |  | 
| Chris Lattner | ddc9401 | 2006-12-12 05:18:19 +0000 | [diff] [blame] | 768 |     case Instruction::IntToPtr: { | 
 | 769 |       // Handle casts to pointers by changing them into casts to the appropriate | 
 | 770 |       // integer type.  This promotes constant folding and simplifies this code. | 
 | 771 |       Constant *Op = CE->getOperand(0); | 
 | 772 |       Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(), false/*ZExt*/); | 
 | 773 |       return EmitConstantValueOnly(Op); | 
 | 774 |     } | 
 | 775 |        | 
 | 776 |        | 
 | 777 |     case Instruction::PtrToInt: { | 
| Chris Lattner | 4a6bd33 | 2006-07-29 01:57:19 +0000 | [diff] [blame] | 778 |       // Support only foldable casts to/from pointers that can be eliminated by | 
 | 779 |       // changing the pointer to the appropriately sized integer type. | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 780 |       Constant *Op = CE->getOperand(0); | 
| Chris Lattner | ddc9401 | 2006-12-12 05:18:19 +0000 | [diff] [blame] | 781 |       const Type *Ty = CE->getType(); | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 782 |  | 
| Chris Lattner | ddc9401 | 2006-12-12 05:18:19 +0000 | [diff] [blame] | 783 |       // We can emit the pointer value into this slot if the slot is an | 
 | 784 |       // integer slot greater or equal to the size of the pointer. | 
| Chris Lattner | 42a7551 | 2007-01-15 02:27:26 +0000 | [diff] [blame] | 785 |       if (Ty->isInteger() && | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 786 |           TD->getABITypeSize(Ty) >= TD->getABITypeSize(Op->getType())) | 
| Chris Lattner | 4a6bd33 | 2006-07-29 01:57:19 +0000 | [diff] [blame] | 787 |         return EmitConstantValueOnly(Op); | 
| Chris Lattner | 4a6bd33 | 2006-07-29 01:57:19 +0000 | [diff] [blame] | 788 |        | 
 | 789 |       assert(0 && "FIXME: Don't yet support this kind of constant cast expr"); | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 790 |       EmitConstantValueOnly(Op); | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 791 |       break; | 
 | 792 |     } | 
 | 793 |     case Instruction::Add: | 
| Anton Korobeynikov | 13b7d3d | 2007-02-04 23:27:42 +0000 | [diff] [blame] | 794 |     case Instruction::Sub: | 
| Anton Korobeynikov | feb8893 | 2007-12-18 20:53:41 +0000 | [diff] [blame] | 795 |     case Instruction::And: | 
 | 796 |     case Instruction::Or: | 
 | 797 |     case Instruction::Xor: | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 798 |       O << "("; | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 799 |       EmitConstantValueOnly(CE->getOperand(0)); | 
| Anton Korobeynikov | feb8893 | 2007-12-18 20:53:41 +0000 | [diff] [blame] | 800 |       O << ")"; | 
 | 801 |       switch (Opcode) { | 
 | 802 |       case Instruction::Add: | 
 | 803 |        O << " + "; | 
 | 804 |        break; | 
 | 805 |       case Instruction::Sub: | 
 | 806 |        O << " - "; | 
 | 807 |        break; | 
 | 808 |       case Instruction::And: | 
 | 809 |        O << " & "; | 
 | 810 |        break; | 
 | 811 |       case Instruction::Or: | 
 | 812 |        O << " | "; | 
 | 813 |        break; | 
 | 814 |       case Instruction::Xor: | 
 | 815 |        O << " ^ "; | 
 | 816 |        break; | 
 | 817 |       default: | 
 | 818 |        break; | 
 | 819 |       } | 
 | 820 |       O << "("; | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 821 |       EmitConstantValueOnly(CE->getOperand(1)); | 
| Chris Lattner | a80ba71 | 2004-08-16 23:15:22 +0000 | [diff] [blame] | 822 |       O << ")"; | 
 | 823 |       break; | 
 | 824 |     default: | 
 | 825 |       assert(0 && "Unsupported operator!"); | 
 | 826 |     } | 
 | 827 |   } else { | 
 | 828 |     assert(0 && "Unknown constant value!"); | 
 | 829 |   } | 
 | 830 | } | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 831 |  | 
| Chris Lattner | 2980cef | 2005-11-10 18:06:33 +0000 | [diff] [blame] | 832 | /// printAsCString - Print the specified array as a C compatible string, only if | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 833 | /// the predicate isString is true. | 
 | 834 | /// | 
| Chris Lattner | 2980cef | 2005-11-10 18:06:33 +0000 | [diff] [blame] | 835 | static void printAsCString(std::ostream &O, const ConstantArray *CVA, | 
 | 836 |                            unsigned LastElt) { | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 837 |   assert(CVA->isString() && "Array is not string compatible!"); | 
 | 838 |  | 
 | 839 |   O << "\""; | 
| Chris Lattner | 2980cef | 2005-11-10 18:06:33 +0000 | [diff] [blame] | 840 |   for (unsigned i = 0; i != LastElt; ++i) { | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 841 |     unsigned char C = | 
| Reid Spencer | b83eb64 | 2006-10-20 07:07:24 +0000 | [diff] [blame] | 842 |         (unsigned char)cast<ConstantInt>(CVA->getOperand(i))->getZExtValue(); | 
| Jim Laskey | f1cdea1 | 2007-01-25 15:12:02 +0000 | [diff] [blame] | 843 |     printStringChar(O, C); | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 844 |   } | 
 | 845 |   O << "\""; | 
 | 846 | } | 
 | 847 |  | 
| Jeff Cohen | c884db4 | 2006-05-02 01:16:28 +0000 | [diff] [blame] | 848 | /// EmitString - Emit a zero-byte-terminated string constant. | 
 | 849 | /// | 
 | 850 | void AsmPrinter::EmitString(const ConstantArray *CVA) const { | 
 | 851 |   unsigned NumElts = CVA->getNumOperands(); | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 852 |   if (TAI->getAscizDirective() && NumElts &&  | 
| Reid Spencer | b83eb64 | 2006-10-20 07:07:24 +0000 | [diff] [blame] | 853 |       cast<ConstantInt>(CVA->getOperand(NumElts-1))->getZExtValue() == 0) { | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 854 |     O << TAI->getAscizDirective(); | 
| Jeff Cohen | c884db4 | 2006-05-02 01:16:28 +0000 | [diff] [blame] | 855 |     printAsCString(O, CVA, NumElts-1); | 
 | 856 |   } else { | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 857 |     O << TAI->getAsciiDirective(); | 
| Jeff Cohen | c884db4 | 2006-05-02 01:16:28 +0000 | [diff] [blame] | 858 |     printAsCString(O, CVA, NumElts); | 
 | 859 |   } | 
 | 860 |   O << "\n"; | 
 | 861 | } | 
 | 862 |  | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 863 | /// EmitGlobalConstant - Print a general LLVM constant to the .s file. | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 864 | /// If Packed is false, pad to the ABI size. | 
 | 865 | void AsmPrinter::EmitGlobalConstant(const Constant *CV, bool Packed) { | 
| Owen Anderson | a69571c | 2006-05-03 01:29:57 +0000 | [diff] [blame] | 866 |   const TargetData *TD = TM.getTargetData(); | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 867 |   unsigned Size = Packed ? | 
 | 868 |     TD->getTypeStoreSize(CV->getType()) : TD->getABITypeSize(CV->getType()); | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 869 |  | 
| Chris Lattner | bd1d382 | 2004-10-16 18:19:26 +0000 | [diff] [blame] | 870 |   if (CV->isNullValue() || isa<UndefValue>(CV)) { | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 871 |     EmitZeros(Size); | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 872 |     return; | 
 | 873 |   } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) { | 
 | 874 |     if (CVA->isString()) { | 
| Jeff Cohen | c884db4 | 2006-05-02 01:16:28 +0000 | [diff] [blame] | 875 |       EmitString(CVA); | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 876 |     } else { // Not a string.  Print the values in successive locations | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 877 |       for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i) | 
 | 878 |         EmitGlobalConstant(CVA->getOperand(i), false); | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 879 |     } | 
 | 880 |     return; | 
 | 881 |   } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) { | 
 | 882 |     // Print the fields in successive locations. Pad to align if needed! | 
| Owen Anderson | a69571c | 2006-05-03 01:29:57 +0000 | [diff] [blame] | 883 |     const StructLayout *cvsLayout = TD->getStructLayout(CVS->getType()); | 
| Chris Lattner | dea18b6 | 2005-01-08 19:59:10 +0000 | [diff] [blame] | 884 |     uint64_t sizeSoFar = 0; | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 885 |     for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) { | 
 | 886 |       const Constant* field = CVS->getOperand(i); | 
 | 887 |  | 
 | 888 |       // Check if padding is needed and insert one or more 0s. | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 889 |       uint64_t fieldSize = TD->getTypeStoreSize(field->getType()); | 
| Duncan Sands | 0c8a13b | 2007-11-05 18:03:02 +0000 | [diff] [blame] | 890 |       uint64_t padSize = ((i == e-1 ? Size : cvsLayout->getElementOffset(i+1)) | 
| Chris Lattner | b1919e2 | 2007-02-10 19:55:17 +0000 | [diff] [blame] | 891 |                           - cvsLayout->getElementOffset(i)) - fieldSize; | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 892 |       sizeSoFar += fieldSize + padSize; | 
 | 893 |  | 
| Duncan Sands | 0c8a13b | 2007-11-05 18:03:02 +0000 | [diff] [blame] | 894 |       // Now print the actual field value without ABI size padding. | 
 | 895 |       EmitGlobalConstant(field, true); | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 896 |  | 
| Duncan Sands | 0c8a13b | 2007-11-05 18:03:02 +0000 | [diff] [blame] | 897 |       // Insert padding - this may include padding to increase the size of the | 
 | 898 |       // current field up to the ABI size (if the struct is not packed) as well | 
 | 899 |       // as padding to ensure that the next field starts at the right offset. | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 900 |       EmitZeros(padSize); | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 901 |     } | 
| Chris Lattner | b0c39a3 | 2007-02-10 19:59:22 +0000 | [diff] [blame] | 902 |     assert(sizeSoFar == cvsLayout->getSizeInBytes() && | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 903 |            "Layout of constant struct may be incorrect!"); | 
 | 904 |     return; | 
 | 905 |   } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { | 
 | 906 |     // FP Constants are printed as integer constants to avoid losing | 
 | 907 |     // precision... | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 908 |     if (CFP->getType() == Type::DoubleTy) { | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 909 |       double Val = CFP->getValueAPF().convertToDouble();  // for comment only | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 910 |       uint64_t i = CFP->getValueAPF().convertToAPInt().getZExtValue(); | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 911 |       if (TAI->getData64bitsDirective()) | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 912 |         O << TAI->getData64bitsDirective() << i << "\t" | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 913 |           << TAI->getCommentString() << " double value: " << Val << "\n"; | 
| Owen Anderson | a69571c | 2006-05-03 01:29:57 +0000 | [diff] [blame] | 914 |       else if (TD->isBigEndian()) { | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 915 |         O << TAI->getData32bitsDirective() << unsigned(i >> 32) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 916 |           << "\t" << TAI->getCommentString() | 
 | 917 |           << " double most significant word " << Val << "\n"; | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 918 |         O << TAI->getData32bitsDirective() << unsigned(i) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 919 |           << "\t" << TAI->getCommentString() | 
 | 920 |           << " double least significant word " << Val << "\n"; | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 921 |       } else { | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 922 |         O << TAI->getData32bitsDirective() << unsigned(i) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 923 |           << "\t" << TAI->getCommentString() | 
 | 924 |           << " double least significant word " << Val << "\n"; | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 925 |         O << TAI->getData32bitsDirective() << unsigned(i >> 32) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 926 |           << "\t" << TAI->getCommentString() | 
 | 927 |           << " double most significant word " << Val << "\n"; | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 928 |       } | 
 | 929 |       return; | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 930 |     } else if (CFP->getType() == Type::FloatTy) { | 
| Dale Johannesen | 3f6eb74 | 2007-09-11 18:32:33 +0000 | [diff] [blame] | 931 |       float Val = CFP->getValueAPF().convertToFloat();  // for comment only | 
 | 932 |       O << TAI->getData32bitsDirective() | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 933 |         << CFP->getValueAPF().convertToAPInt().getZExtValue() | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 934 |         << "\t" << TAI->getCommentString() << " float " << Val << "\n"; | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 935 |       return; | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 936 |     } else if (CFP->getType() == Type::X86_FP80Ty) { | 
 | 937 |       // all long double variants are printed as hex | 
| Dale Johannesen | 693717f | 2007-09-26 23:20:33 +0000 | [diff] [blame] | 938 |       // api needed to prevent premature destruction | 
 | 939 |       APInt api = CFP->getValueAPF().convertToAPInt(); | 
 | 940 |       const uint64_t *p = api.getRawData(); | 
| Chris Lattner | 553c116 | 2008-01-27 06:09:28 +0000 | [diff] [blame] | 941 |       APFloat DoubleVal = CFP->getValueAPF(); | 
 | 942 |       DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven); | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 943 |       if (TD->isBigEndian()) { | 
 | 944 |         O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48) | 
 | 945 |           << "\t" << TAI->getCommentString() | 
| Chris Lattner | 553c116 | 2008-01-27 06:09:28 +0000 | [diff] [blame] | 946 |           << " long double most significant halfword of ~" | 
 | 947 |           << DoubleVal.convertToDouble() << "\n"; | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 948 |         O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32) | 
 | 949 |           << "\t" << TAI->getCommentString() | 
 | 950 |           << " long double next halfword\n"; | 
 | 951 |         O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16) | 
 | 952 |           << "\t" << TAI->getCommentString() | 
 | 953 |           << " long double next halfword\n"; | 
 | 954 |         O << TAI->getData16bitsDirective() << uint16_t(p[0]) | 
 | 955 |           << "\t" << TAI->getCommentString() | 
 | 956 |           << " long double next halfword\n"; | 
 | 957 |         O << TAI->getData16bitsDirective() << uint16_t(p[1]) | 
 | 958 |           << "\t" << TAI->getCommentString() | 
 | 959 |           << " long double least significant halfword\n"; | 
 | 960 |        } else { | 
 | 961 |         O << TAI->getData16bitsDirective() << uint16_t(p[1]) | 
 | 962 |           << "\t" << TAI->getCommentString() | 
| Chris Lattner | 553c116 | 2008-01-27 06:09:28 +0000 | [diff] [blame] | 963 |           << " long double least significant halfword of ~" | 
 | 964 |           << DoubleVal.convertToDouble() << "\n"; | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 965 |         O << TAI->getData16bitsDirective() << uint16_t(p[0]) | 
 | 966 |           << "\t" << TAI->getCommentString() | 
 | 967 |           << " long double next halfword\n"; | 
 | 968 |         O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16) | 
 | 969 |           << "\t" << TAI->getCommentString() | 
 | 970 |           << " long double next halfword\n"; | 
 | 971 |         O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32) | 
 | 972 |           << "\t" << TAI->getCommentString() | 
 | 973 |           << " long double next halfword\n"; | 
 | 974 |         O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48) | 
 | 975 |           << "\t" << TAI->getCommentString() | 
 | 976 |           << " long double most significant halfword\n"; | 
 | 977 |       } | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 978 |       EmitZeros(Size - TD->getTypeStoreSize(Type::X86_FP80Ty)); | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 979 |       return; | 
| Dale Johannesen | fcf4d24 | 2007-10-11 23:32:15 +0000 | [diff] [blame] | 980 |     } else if (CFP->getType() == Type::PPC_FP128Ty) { | 
 | 981 |       // all long double variants are printed as hex | 
 | 982 |       // api needed to prevent premature destruction | 
 | 983 |       APInt api = CFP->getValueAPF().convertToAPInt(); | 
 | 984 |       const uint64_t *p = api.getRawData(); | 
 | 985 |       if (TD->isBigEndian()) { | 
 | 986 |         O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32) | 
 | 987 |           << "\t" << TAI->getCommentString() | 
 | 988 |           << " long double most significant word\n"; | 
 | 989 |         O << TAI->getData32bitsDirective() << uint32_t(p[0]) | 
 | 990 |           << "\t" << TAI->getCommentString() | 
 | 991 |           << " long double next word\n"; | 
 | 992 |         O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32) | 
 | 993 |           << "\t" << TAI->getCommentString() | 
 | 994 |           << " long double next word\n"; | 
 | 995 |         O << TAI->getData32bitsDirective() << uint32_t(p[1]) | 
 | 996 |           << "\t" << TAI->getCommentString() | 
 | 997 |           << " long double least significant word\n"; | 
 | 998 |        } else { | 
 | 999 |         O << TAI->getData32bitsDirective() << uint32_t(p[1]) | 
 | 1000 |           << "\t" << TAI->getCommentString() | 
 | 1001 |           << " long double least significant word\n"; | 
 | 1002 |         O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32) | 
 | 1003 |           << "\t" << TAI->getCommentString() | 
 | 1004 |           << " long double next word\n"; | 
 | 1005 |         O << TAI->getData32bitsDirective() << uint32_t(p[0]) | 
 | 1006 |           << "\t" << TAI->getCommentString() | 
 | 1007 |           << " long double next word\n"; | 
 | 1008 |         O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32) | 
 | 1009 |           << "\t" << TAI->getCommentString() | 
 | 1010 |           << " long double most significant word\n"; | 
 | 1011 |       } | 
 | 1012 |       return; | 
| Dale Johannesen | 9d5f456 | 2007-09-12 03:30:33 +0000 | [diff] [blame] | 1013 |     } else assert(0 && "Floating point constant type not handled"); | 
| Reid Spencer | 4785781 | 2006-12-31 05:55:36 +0000 | [diff] [blame] | 1014 |   } else if (CV->getType() == Type::Int64Ty) { | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 1015 |     if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { | 
| Reid Spencer | b83eb64 | 2006-10-20 07:07:24 +0000 | [diff] [blame] | 1016 |       uint64_t Val = CI->getZExtValue(); | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 1017 |  | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 1018 |       if (TAI->getData64bitsDirective()) | 
 | 1019 |         O << TAI->getData64bitsDirective() << Val << "\n"; | 
| Owen Anderson | a69571c | 2006-05-03 01:29:57 +0000 | [diff] [blame] | 1020 |       else if (TD->isBigEndian()) { | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 1021 |         O << TAI->getData32bitsDirective() << unsigned(Val >> 32) | 
 | 1022 |           << "\t" << TAI->getCommentString() | 
 | 1023 |           << " Double-word most significant word " << Val << "\n"; | 
 | 1024 |         O << TAI->getData32bitsDirective() << unsigned(Val) | 
 | 1025 |           << "\t" << TAI->getCommentString() | 
 | 1026 |           << " Double-word least significant word " << Val << "\n"; | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 1027 |       } else { | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 1028 |         O << TAI->getData32bitsDirective() << unsigned(Val) | 
 | 1029 |           << "\t" << TAI->getCommentString() | 
 | 1030 |           << " Double-word least significant word " << Val << "\n"; | 
 | 1031 |         O << TAI->getData32bitsDirective() << unsigned(Val >> 32) | 
 | 1032 |           << "\t" << TAI->getCommentString() | 
 | 1033 |           << " Double-word most significant word " << Val << "\n"; | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 1034 |       } | 
 | 1035 |       return; | 
 | 1036 |     } | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 1037 |   } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { | 
 | 1038 |     const VectorType *PTy = CP->getType(); | 
| Nate Begeman | 8cfa57b | 2005-12-06 06:18:55 +0000 | [diff] [blame] | 1039 |      | 
 | 1040 |     for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I) | 
| Duncan Sands | ca0ed74 | 2007-11-05 00:04:43 +0000 | [diff] [blame] | 1041 |       EmitGlobalConstant(CP->getOperand(I), false); | 
| Nate Begeman | 8cfa57b | 2005-12-06 06:18:55 +0000 | [diff] [blame] | 1042 |      | 
 | 1043 |     return; | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 1044 |   } | 
 | 1045 |  | 
 | 1046 |   const Type *type = CV->getType(); | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 1047 |   printDataDirective(type); | 
| Chris Lattner | 25045bd | 2005-11-21 07:51:36 +0000 | [diff] [blame] | 1048 |   EmitConstantValueOnly(CV); | 
| Chris Lattner | 1b7e235 | 2004-08-17 06:36:49 +0000 | [diff] [blame] | 1049 |   O << "\n"; | 
 | 1050 | } | 
| Chris Lattner | 0264d1a | 2006-01-27 02:10:10 +0000 | [diff] [blame] | 1051 |  | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 1052 | void | 
 | 1053 | AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { | 
 | 1054 |   // Target doesn't support this yet! | 
 | 1055 |   abort(); | 
 | 1056 | } | 
 | 1057 |  | 
| Chris Lattner | 3ce9b67 | 2006-09-26 23:59:50 +0000 | [diff] [blame] | 1058 | /// PrintSpecial - Print information related to the specified machine instr | 
 | 1059 | /// that is independent of the operand, and may be independent of the instr | 
 | 1060 | /// itself.  This can be useful for portably encoding the comment character | 
 | 1061 | /// or other bits of target-specific knowledge into the asmstrings.  The | 
 | 1062 | /// syntax used is ${:comment}.  Targets can override this to add support | 
 | 1063 | /// for their own strange codes. | 
 | 1064 | void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) { | 
| Chris Lattner | bae02cf | 2006-09-27 00:06:07 +0000 | [diff] [blame] | 1065 |   if (!strcmp(Code, "private")) { | 
 | 1066 |     O << TAI->getPrivateGlobalPrefix(); | 
 | 1067 |   } else if (!strcmp(Code, "comment")) { | 
| Chris Lattner | 3ce9b67 | 2006-09-26 23:59:50 +0000 | [diff] [blame] | 1068 |     O << TAI->getCommentString(); | 
 | 1069 |   } else if (!strcmp(Code, "uid")) { | 
 | 1070 |     // Assign a unique ID to this machine instruction. | 
 | 1071 |     static const MachineInstr *LastMI = 0; | 
| Chris Lattner | b6a24bf | 2007-02-05 21:23:52 +0000 | [diff] [blame] | 1072 |     static const Function *F = 0; | 
| Chris Lattner | 3ce9b67 | 2006-09-26 23:59:50 +0000 | [diff] [blame] | 1073 |     static unsigned Counter = 0U-1; | 
| Chris Lattner | b6a24bf | 2007-02-05 21:23:52 +0000 | [diff] [blame] | 1074 |  | 
 | 1075 |     // Comparing the address of MI isn't sufficient, because machineinstrs may | 
 | 1076 |     // be allocated to the same address across functions. | 
 | 1077 |     const Function *ThisF = MI->getParent()->getParent()->getFunction(); | 
 | 1078 |      | 
| Chris Lattner | 3ce9b67 | 2006-09-26 23:59:50 +0000 | [diff] [blame] | 1079 |     // If this is a new machine instruction, bump the counter. | 
| Chris Lattner | b6a24bf | 2007-02-05 21:23:52 +0000 | [diff] [blame] | 1080 |     if (LastMI != MI || F != ThisF) { | 
 | 1081 |       ++Counter; | 
 | 1082 |       LastMI = MI; | 
| Chris Lattner | 4b09252 | 2007-02-06 01:56:31 +0000 | [diff] [blame] | 1083 |       F = ThisF; | 
| Chris Lattner | b6a24bf | 2007-02-05 21:23:52 +0000 | [diff] [blame] | 1084 |     } | 
| Chris Lattner | 3ce9b67 | 2006-09-26 23:59:50 +0000 | [diff] [blame] | 1085 |     O << Counter; | 
 | 1086 |   } else { | 
| Bill Wendling | e815619 | 2006-12-07 01:30:32 +0000 | [diff] [blame] | 1087 |     cerr << "Unknown special formatter '" << Code | 
 | 1088 |          << "' for machine instr: " << *MI; | 
| Chris Lattner | 3ce9b67 | 2006-09-26 23:59:50 +0000 | [diff] [blame] | 1089 |     exit(1); | 
 | 1090 |   }     | 
 | 1091 | } | 
 | 1092 |  | 
 | 1093 |  | 
| Chris Lattner | 0264d1a | 2006-01-27 02:10:10 +0000 | [diff] [blame] | 1094 | /// printInlineAsm - This method formats and prints the specified machine | 
 | 1095 | /// instruction that is an inline asm. | 
 | 1096 | void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { | 
| Chris Lattner | f2b67cf | 2006-01-30 23:00:08 +0000 | [diff] [blame] | 1097 |   unsigned NumOperands = MI->getNumOperands(); | 
 | 1098 |    | 
 | 1099 |   // Count the number of register definitions. | 
 | 1100 |   unsigned NumDefs = 0; | 
| Dan Gohman | 92dfe20 | 2007-09-14 20:33:02 +0000 | [diff] [blame] | 1101 |   for (; MI->getOperand(NumDefs).isRegister() && MI->getOperand(NumDefs).isDef(); | 
| Chris Lattner | 67942f5 | 2006-09-05 20:02:51 +0000 | [diff] [blame] | 1102 |        ++NumDefs) | 
| Chris Lattner | f2b67cf | 2006-01-30 23:00:08 +0000 | [diff] [blame] | 1103 |     assert(NumDefs != NumOperands-1 && "No asm string?"); | 
 | 1104 |    | 
 | 1105 |   assert(MI->getOperand(NumDefs).isExternalSymbol() && "No asm string?"); | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1106 |  | 
 | 1107 |   // Disassemble the AsmStr, printing out the literal pieces, the operands, etc. | 
| Chris Lattner | f2b67cf | 2006-01-30 23:00:08 +0000 | [diff] [blame] | 1108 |   const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1109 |  | 
| Dale Johannesen | ba2a0b9 | 2008-01-29 02:21:21 +0000 | [diff] [blame] | 1110 |   // If this asmstr is empty, just print the #APP/#NOAPP markers. | 
 | 1111 |   // These are useful to see where empty asm's wound up. | 
| Chris Lattner | f26f5dd | 2006-07-28 00:17:20 +0000 | [diff] [blame] | 1112 |   if (AsmStr[0] == 0) { | 
| Dale Johannesen | ba2a0b9 | 2008-01-29 02:21:21 +0000 | [diff] [blame] | 1113 |     O << TAI->getInlineAsmStart() << "\n\t" << TAI->getInlineAsmEnd() << "\n"; | 
| Chris Lattner | f26f5dd | 2006-07-28 00:17:20 +0000 | [diff] [blame] | 1114 |     return; | 
 | 1115 |   } | 
 | 1116 |    | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 1117 |   O << TAI->getInlineAsmStart() << "\n\t"; | 
| Chris Lattner | f26f5dd | 2006-07-28 00:17:20 +0000 | [diff] [blame] | 1118 |  | 
| Bill Wendling | eb9a42c | 2007-01-16 03:42:04 +0000 | [diff] [blame] | 1119 |   // The variant of the current asmprinter. | 
 | 1120 |   int AsmPrinterVariant = TAI->getAssemblerDialect(); | 
 | 1121 |  | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1122 |   int CurVariant = -1;            // The number of the {.|.|.} region we are in. | 
 | 1123 |   const char *LastEmitted = AsmStr; // One past the last character emitted. | 
| Chris Lattner | 2cc2f66 | 2006-02-01 01:28:23 +0000 | [diff] [blame] | 1124 |    | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1125 |   while (*LastEmitted) { | 
 | 1126 |     switch (*LastEmitted) { | 
 | 1127 |     default: { | 
 | 1128 |       // Not a special case, emit the string section literally. | 
 | 1129 |       const char *LiteralEnd = LastEmitted+1; | 
 | 1130 |       while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' && | 
| Chris Lattner | 1c05997 | 2006-05-05 21:47:05 +0000 | [diff] [blame] | 1131 |              *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n') | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1132 |         ++LiteralEnd; | 
 | 1133 |       if (CurVariant == -1 || CurVariant == AsmPrinterVariant) | 
 | 1134 |         O.write(LastEmitted, LiteralEnd-LastEmitted); | 
 | 1135 |       LastEmitted = LiteralEnd; | 
 | 1136 |       break; | 
 | 1137 |     } | 
| Chris Lattner | 1c05997 | 2006-05-05 21:47:05 +0000 | [diff] [blame] | 1138 |     case '\n': | 
 | 1139 |       ++LastEmitted;   // Consume newline character. | 
| Chris Lattner | 1f6f4c7 | 2007-04-30 17:00:18 +0000 | [diff] [blame] | 1140 |       O << "\n";       // Indent code with newline. | 
| Chris Lattner | 1c05997 | 2006-05-05 21:47:05 +0000 | [diff] [blame] | 1141 |       break; | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1142 |     case '$': { | 
 | 1143 |       ++LastEmitted;   // Consume '$' character. | 
| Chris Lattner | faf1dae | 2006-10-03 23:27:09 +0000 | [diff] [blame] | 1144 |       bool Done = true; | 
 | 1145 |  | 
 | 1146 |       // Handle escapes. | 
 | 1147 |       switch (*LastEmitted) { | 
 | 1148 |       default: Done = false; break; | 
 | 1149 |       case '$':     // $$ -> $ | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1150 |         if (CurVariant == -1 || CurVariant == AsmPrinterVariant) | 
 | 1151 |           O << '$'; | 
 | 1152 |         ++LastEmitted;  // Consume second '$' character. | 
 | 1153 |         break; | 
| Chris Lattner | faf1dae | 2006-10-03 23:27:09 +0000 | [diff] [blame] | 1154 |       case '(':             // $( -> same as GCC's { character. | 
 | 1155 |         ++LastEmitted;      // Consume '(' character. | 
 | 1156 |         if (CurVariant != -1) { | 
| Bill Wendling | e815619 | 2006-12-07 01:30:32 +0000 | [diff] [blame] | 1157 |           cerr << "Nested variants found in inline asm string: '" | 
 | 1158 |                << AsmStr << "'\n"; | 
| Chris Lattner | faf1dae | 2006-10-03 23:27:09 +0000 | [diff] [blame] | 1159 |           exit(1); | 
 | 1160 |         } | 
 | 1161 |         CurVariant = 0;     // We're in the first variant now. | 
 | 1162 |         break; | 
 | 1163 |       case '|': | 
 | 1164 |         ++LastEmitted;  // consume '|' character. | 
 | 1165 |         if (CurVariant == -1) { | 
| Bill Wendling | e815619 | 2006-12-07 01:30:32 +0000 | [diff] [blame] | 1166 |           cerr << "Found '|' character outside of variant in inline asm " | 
 | 1167 |                << "string: '" << AsmStr << "'\n"; | 
| Chris Lattner | faf1dae | 2006-10-03 23:27:09 +0000 | [diff] [blame] | 1168 |           exit(1); | 
 | 1169 |         } | 
 | 1170 |         ++CurVariant;   // We're in the next variant. | 
 | 1171 |         break; | 
 | 1172 |       case ')':         // $) -> same as GCC's } char. | 
 | 1173 |         ++LastEmitted;  // consume ')' character. | 
 | 1174 |         if (CurVariant == -1) { | 
| Bill Wendling | e815619 | 2006-12-07 01:30:32 +0000 | [diff] [blame] | 1175 |           cerr << "Found '}' character outside of variant in inline asm " | 
 | 1176 |                << "string: '" << AsmStr << "'\n"; | 
| Chris Lattner | faf1dae | 2006-10-03 23:27:09 +0000 | [diff] [blame] | 1177 |           exit(1); | 
 | 1178 |         } | 
 | 1179 |         CurVariant = -1; | 
 | 1180 |         break; | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1181 |       } | 
| Chris Lattner | faf1dae | 2006-10-03 23:27:09 +0000 | [diff] [blame] | 1182 |       if (Done) break; | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1183 |        | 
 | 1184 |       bool HasCurlyBraces = false; | 
 | 1185 |       if (*LastEmitted == '{') {     // ${variable} | 
 | 1186 |         ++LastEmitted;               // Consume '{' character. | 
 | 1187 |         HasCurlyBraces = true; | 
 | 1188 |       } | 
 | 1189 |        | 
 | 1190 |       const char *IDStart = LastEmitted; | 
 | 1191 |       char *IDEnd; | 
| Chris Lattner | fad2912 | 2007-01-23 00:36:17 +0000 | [diff] [blame] | 1192 |       errno = 0; | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1193 |       long Val = strtol(IDStart, &IDEnd, 10); // We only accept numbers for IDs. | 
 | 1194 |       if (!isdigit(*IDStart) || (Val == 0 && errno == EINVAL)) { | 
| Bill Wendling | e815619 | 2006-12-07 01:30:32 +0000 | [diff] [blame] | 1195 |         cerr << "Bad $ operand number in inline asm string: '"  | 
 | 1196 |              << AsmStr << "'\n"; | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1197 |         exit(1); | 
 | 1198 |       } | 
 | 1199 |       LastEmitted = IDEnd; | 
 | 1200 |        | 
| Chris Lattner | a36cb0a | 2006-02-06 22:17:23 +0000 | [diff] [blame] | 1201 |       char Modifier[2] = { 0, 0 }; | 
 | 1202 |        | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1203 |       if (HasCurlyBraces) { | 
| Chris Lattner | a36cb0a | 2006-02-06 22:17:23 +0000 | [diff] [blame] | 1204 |         // If we have curly braces, check for a modifier character.  This | 
 | 1205 |         // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm. | 
 | 1206 |         if (*LastEmitted == ':') { | 
 | 1207 |           ++LastEmitted;    // Consume ':' character. | 
 | 1208 |           if (*LastEmitted == 0) { | 
| Bill Wendling | e815619 | 2006-12-07 01:30:32 +0000 | [diff] [blame] | 1209 |             cerr << "Bad ${:} expression in inline asm string: '"  | 
 | 1210 |                  << AsmStr << "'\n"; | 
| Chris Lattner | a36cb0a | 2006-02-06 22:17:23 +0000 | [diff] [blame] | 1211 |             exit(1); | 
 | 1212 |           } | 
 | 1213 |            | 
 | 1214 |           Modifier[0] = *LastEmitted; | 
 | 1215 |           ++LastEmitted;    // Consume modifier character. | 
 | 1216 |         } | 
 | 1217 |          | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1218 |         if (*LastEmitted != '}') { | 
| Bill Wendling | e815619 | 2006-12-07 01:30:32 +0000 | [diff] [blame] | 1219 |           cerr << "Bad ${} expression in inline asm string: '"  | 
 | 1220 |                << AsmStr << "'\n"; | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1221 |           exit(1); | 
 | 1222 |         } | 
 | 1223 |         ++LastEmitted;    // Consume '}' character. | 
 | 1224 |       } | 
 | 1225 |        | 
 | 1226 |       if ((unsigned)Val >= NumOperands-1) { | 
| Bill Wendling | e815619 | 2006-12-07 01:30:32 +0000 | [diff] [blame] | 1227 |         cerr << "Invalid $ operand number in inline asm string: '"  | 
 | 1228 |              << AsmStr << "'\n"; | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1229 |         exit(1); | 
 | 1230 |       } | 
 | 1231 |        | 
| Chris Lattner | c3a9f8d | 2006-02-23 19:21:04 +0000 | [diff] [blame] | 1232 |       // Okay, we finally have a value number.  Ask the target to print this | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1233 |       // operand! | 
| Chris Lattner | c3a9f8d | 2006-02-23 19:21:04 +0000 | [diff] [blame] | 1234 |       if (CurVariant == -1 || CurVariant == AsmPrinterVariant) { | 
 | 1235 |         unsigned OpNo = 1; | 
| Chris Lattner | fd561cd | 2006-06-08 18:00:47 +0000 | [diff] [blame] | 1236 |  | 
 | 1237 |         bool Error = false; | 
 | 1238 |  | 
| Chris Lattner | c3a9f8d | 2006-02-23 19:21:04 +0000 | [diff] [blame] | 1239 |         // Scan to find the machine operand number for the operand. | 
| Chris Lattner | daf6bc6 | 2006-02-24 19:50:58 +0000 | [diff] [blame] | 1240 |         for (; Val; --Val) { | 
| Chris Lattner | fd561cd | 2006-06-08 18:00:47 +0000 | [diff] [blame] | 1241 |           if (OpNo >= MI->getNumOperands()) break; | 
| Chris Lattner | 9e33049 | 2007-12-30 20:50:28 +0000 | [diff] [blame] | 1242 |           unsigned OpFlags = MI->getOperand(OpNo).getImm(); | 
| Chris Lattner | daf6bc6 | 2006-02-24 19:50:58 +0000 | [diff] [blame] | 1243 |           OpNo += (OpFlags >> 3) + 1; | 
 | 1244 |         } | 
| Chris Lattner | dd26033 | 2006-02-24 20:21:58 +0000 | [diff] [blame] | 1245 |  | 
| Chris Lattner | fd561cd | 2006-06-08 18:00:47 +0000 | [diff] [blame] | 1246 |         if (OpNo >= MI->getNumOperands()) { | 
 | 1247 |           Error = true; | 
| Chris Lattner | dd26033 | 2006-02-24 20:21:58 +0000 | [diff] [blame] | 1248 |         } else { | 
| Chris Lattner | 9e33049 | 2007-12-30 20:50:28 +0000 | [diff] [blame] | 1249 |           unsigned OpFlags = MI->getOperand(OpNo).getImm(); | 
| Chris Lattner | fd561cd | 2006-06-08 18:00:47 +0000 | [diff] [blame] | 1250 |           ++OpNo;  // Skip over the ID number. | 
 | 1251 |  | 
| Dale Johannesen | eb57ea7 | 2007-11-05 21:20:28 +0000 | [diff] [blame] | 1252 |           if (Modifier[0]=='l')  // labels are target independent | 
| Chris Lattner | 8aa797a | 2007-12-30 23:10:15 +0000 | [diff] [blame] | 1253 |             printBasicBlockLabel(MI->getOperand(OpNo).getMBB(),  | 
| Dale Johannesen | eb57ea7 | 2007-11-05 21:20:28 +0000 | [diff] [blame] | 1254 |                                  false, false); | 
 | 1255 |           else { | 
 | 1256 |             AsmPrinter *AP = const_cast<AsmPrinter*>(this); | 
 | 1257 |             if ((OpFlags & 7) == 4 /*ADDR MODE*/) { | 
 | 1258 |               Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant, | 
 | 1259 |                                                 Modifier[0] ? Modifier : 0); | 
 | 1260 |             } else { | 
 | 1261 |               Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant, | 
 | 1262 |                                           Modifier[0] ? Modifier : 0); | 
 | 1263 |             } | 
| Chris Lattner | fd561cd | 2006-06-08 18:00:47 +0000 | [diff] [blame] | 1264 |           } | 
| Chris Lattner | dd26033 | 2006-02-24 20:21:58 +0000 | [diff] [blame] | 1265 |         } | 
 | 1266 |         if (Error) { | 
| Bill Wendling | e815619 | 2006-12-07 01:30:32 +0000 | [diff] [blame] | 1267 |           cerr << "Invalid operand found in inline asm: '" | 
 | 1268 |                << AsmStr << "'\n"; | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1269 |           MI->dump(); | 
 | 1270 |           exit(1); | 
 | 1271 |         } | 
| Chris Lattner | c3a9f8d | 2006-02-23 19:21:04 +0000 | [diff] [blame] | 1272 |       } | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1273 |       break; | 
 | 1274 |     } | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1275 |     } | 
 | 1276 |   } | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 1277 |   O << "\n\t" << TAI->getInlineAsmEnd() << "\n"; | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1278 | } | 
 | 1279 |  | 
| Jim Laskey | 1ee2925 | 2007-01-26 14:34:52 +0000 | [diff] [blame] | 1280 | /// printLabel - This method prints a local label used by debug and | 
 | 1281 | /// exception handling tables. | 
 | 1282 | void AsmPrinter::printLabel(const MachineInstr *MI) const { | 
| Evan Cheng | 4eecdeb | 2008-02-02 08:39:46 +0000 | [diff] [blame] | 1283 |   O << TAI->getPrivateGlobalPrefix() | 
| Chris Lattner | 9e33049 | 2007-12-30 20:50:28 +0000 | [diff] [blame] | 1284 |     << "label" << MI->getOperand(0).getImm() << ":\n"; | 
| Jim Laskey | 1ee2925 | 2007-01-26 14:34:52 +0000 | [diff] [blame] | 1285 | } | 
 | 1286 |  | 
| Evan Cheng | 1b08bbc | 2008-02-01 09:10:45 +0000 | [diff] [blame] | 1287 | void AsmPrinter::printLabel(unsigned Id) const { | 
| Evan Cheng | 4eecdeb | 2008-02-02 08:39:46 +0000 | [diff] [blame] | 1288 |   O << TAI->getPrivateGlobalPrefix() << "label" << Id << ":\n"; | 
| Evan Cheng | 1b08bbc | 2008-02-01 09:10:45 +0000 | [diff] [blame] | 1289 | } | 
 | 1290 |  | 
| Evan Cheng | a844bde | 2008-02-02 04:07:54 +0000 | [diff] [blame] | 1291 | /// printDeclare - This method prints a local variable declaration used by | 
 | 1292 | /// debug tables. | 
| Evan Cheng | 4e3f5a4 | 2008-02-04 23:06:48 +0000 | [diff] [blame] | 1293 | /// FIXME: It doesn't really print anything rather it inserts a DebugVariable | 
 | 1294 | /// entry into dwarf table. | 
| Evan Cheng | a844bde | 2008-02-02 04:07:54 +0000 | [diff] [blame] | 1295 | void AsmPrinter::printDeclare(const MachineInstr *MI) const { | 
| Evan Cheng | 4e3f5a4 | 2008-02-04 23:06:48 +0000 | [diff] [blame] | 1296 |   int FI = MI->getOperand(0).getIndex(); | 
 | 1297 |   GlobalValue *GV = MI->getOperand(1).getGlobal(); | 
 | 1298 |   MMI->RecordVariable(GV, FI); | 
| Evan Cheng | a844bde | 2008-02-02 04:07:54 +0000 | [diff] [blame] | 1299 | } | 
 | 1300 |  | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1301 | /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM | 
 | 1302 | /// instruction, using the specified assembler variant.  Targets should | 
 | 1303 | /// overried this to format as appropriate. | 
 | 1304 | bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, | 
| Chris Lattner | a36cb0a | 2006-02-06 22:17:23 +0000 | [diff] [blame] | 1305 |                                  unsigned AsmVariant, const char *ExtraCode) { | 
| Chris Lattner | 6609913 | 2006-02-01 22:41:11 +0000 | [diff] [blame] | 1306 |   // Target doesn't support this yet! | 
 | 1307 |   return true; | 
| Chris Lattner | 0264d1a | 2006-01-27 02:10:10 +0000 | [diff] [blame] | 1308 | } | 
| Chris Lattner | dd26033 | 2006-02-24 20:21:58 +0000 | [diff] [blame] | 1309 |  | 
 | 1310 | bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, | 
 | 1311 |                                        unsigned AsmVariant, | 
 | 1312 |                                        const char *ExtraCode) { | 
 | 1313 |   // Target doesn't support this yet! | 
 | 1314 |   return true; | 
 | 1315 | } | 
| Nate Begeman | 37efe67 | 2006-04-22 18:53:45 +0000 | [diff] [blame] | 1316 |  | 
 | 1317 | /// printBasicBlockLabel - This method prints the label for the specified | 
 | 1318 | /// MachineBasicBlock | 
| Nate Begeman | cdf38c4 | 2006-05-02 05:37:32 +0000 | [diff] [blame] | 1319 | void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, | 
 | 1320 |                                       bool printColon, | 
 | 1321 |                                       bool printComment) const { | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 1322 |   O << TAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber() << "_" | 
 | 1323 |     << MBB->getNumber(); | 
| Nate Begeman | cdf38c4 | 2006-05-02 05:37:32 +0000 | [diff] [blame] | 1324 |   if (printColon) | 
 | 1325 |     O << ':'; | 
| Chris Lattner | 9c78ecb | 2006-10-05 21:40:14 +0000 | [diff] [blame] | 1326 |   if (printComment && MBB->getBasicBlock()) | 
| Dan Gohman | 286d569 | 2007-07-30 15:06:25 +0000 | [diff] [blame] | 1327 |     O << '\t' << TAI->getCommentString() << ' ' | 
 | 1328 |       << MBB->getBasicBlock()->getName(); | 
| Nate Begeman | 37efe67 | 2006-04-22 18:53:45 +0000 | [diff] [blame] | 1329 | } | 
| Nate Begeman | 52a51e38 | 2006-08-12 21:29:52 +0000 | [diff] [blame] | 1330 |  | 
| Evan Cheng | cc41586 | 2007-11-09 01:32:10 +0000 | [diff] [blame] | 1331 | /// printPICJumpTableSetLabel - This method prints a set label for the | 
 | 1332 | /// specified MachineBasicBlock for a jumptable entry. | 
 | 1333 | void AsmPrinter::printPICJumpTableSetLabel(unsigned uid,  | 
 | 1334 |                                            const MachineBasicBlock *MBB) const { | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 1335 |   if (!TAI->getSetDirective()) | 
| Nate Begeman | 52a51e38 | 2006-08-12 21:29:52 +0000 | [diff] [blame] | 1336 |     return; | 
 | 1337 |    | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 1338 |   O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 1339 |     << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; | 
| Nate Begeman | 52a51e38 | 2006-08-12 21:29:52 +0000 | [diff] [blame] | 1340 |   printBasicBlockLabel(MBB, false, false); | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 1341 |   O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()  | 
 | 1342 |     << '_' << uid << '\n'; | 
| Nate Begeman | 52a51e38 | 2006-08-12 21:29:52 +0000 | [diff] [blame] | 1343 | } | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 1344 |  | 
| Evan Cheng | cc41586 | 2007-11-09 01:32:10 +0000 | [diff] [blame] | 1345 | void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2, | 
 | 1346 |                                            const MachineBasicBlock *MBB) const { | 
| Evan Cheng | 41349c1 | 2006-11-01 09:23:08 +0000 | [diff] [blame] | 1347 |   if (!TAI->getSetDirective()) | 
 | 1348 |     return; | 
 | 1349 |    | 
 | 1350 |   O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 1351 |     << getFunctionNumber() << '_' << uid << '_' << uid2 | 
 | 1352 |     << "_set_" << MBB->getNumber() << ','; | 
| Evan Cheng | 41349c1 | 2006-11-01 09:23:08 +0000 | [diff] [blame] | 1353 |   printBasicBlockLabel(MBB, false, false); | 
| Evan Cheng | 347d39f | 2007-10-14 05:57:21 +0000 | [diff] [blame] | 1354 |   O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()  | 
 | 1355 |     << '_' << uid << '_' << uid2 << '\n'; | 
| Evan Cheng | 41349c1 | 2006-11-01 09:23:08 +0000 | [diff] [blame] | 1356 | } | 
 | 1357 |  | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 1358 | /// printDataDirective - This method prints the asm directive for the | 
 | 1359 | /// specified type. | 
 | 1360 | void AsmPrinter::printDataDirective(const Type *type) { | 
 | 1361 |   const TargetData *TD = TM.getTargetData(); | 
 | 1362 |   switch (type->getTypeID()) { | 
| Reid Spencer | a54b7cb | 2007-01-12 07:05:14 +0000 | [diff] [blame] | 1363 |   case Type::IntegerTyID: { | 
 | 1364 |     unsigned BitWidth = cast<IntegerType>(type)->getBitWidth(); | 
 | 1365 |     if (BitWidth <= 8) | 
 | 1366 |       O << TAI->getData8bitsDirective(); | 
 | 1367 |     else if (BitWidth <= 16) | 
 | 1368 |       O << TAI->getData16bitsDirective(); | 
 | 1369 |     else if (BitWidth <= 32) | 
 | 1370 |       O << TAI->getData32bitsDirective(); | 
 | 1371 |     else if (BitWidth <= 64) { | 
 | 1372 |       assert(TAI->getData64bitsDirective() && | 
 | 1373 |              "Target cannot handle 64-bit constant exprs!"); | 
 | 1374 |       O << TAI->getData64bitsDirective(); | 
 | 1375 |     } | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 1376 |     break; | 
| Reid Spencer | a54b7cb | 2007-01-12 07:05:14 +0000 | [diff] [blame] | 1377 |   } | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 1378 |   case Type::PointerTyID: | 
 | 1379 |     if (TD->getPointerSize() == 8) { | 
 | 1380 |       assert(TAI->getData64bitsDirective() && | 
 | 1381 |              "Target cannot handle 64-bit pointer exprs!"); | 
 | 1382 |       O << TAI->getData64bitsDirective(); | 
| Reid Spencer | a54b7cb | 2007-01-12 07:05:14 +0000 | [diff] [blame] | 1383 |     } else { | 
 | 1384 |       O << TAI->getData32bitsDirective(); | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 1385 |     } | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 1386 |     break; | 
 | 1387 |   case Type::FloatTyID: case Type::DoubleTyID: | 
| Dale Johannesen | 4292d1c | 2007-09-28 18:06:58 +0000 | [diff] [blame] | 1388 |   case Type::X86_FP80TyID: case Type::FP128TyID: case Type::PPC_FP128TyID: | 
| Evan Cheng | d6594ae | 2006-09-12 21:00:35 +0000 | [diff] [blame] | 1389 |     assert (0 && "Should have already output floating point constant."); | 
 | 1390 |   default: | 
 | 1391 |     assert (0 && "Can't handle printing this type of thing"); | 
 | 1392 |     break; | 
 | 1393 |   } | 
 | 1394 | } | 
| Dale Johannesen | 4c3a5f8 | 2007-02-16 01:54:53 +0000 | [diff] [blame] | 1395 |  |