| Chris Lattner | b36cbd0 | 2005-07-01 22:44:09 +0000 | [diff] [blame] | 1 | //===-- X86AsmPrinter.cpp - Convert X86 LLVM IR to X86 assembly -----------===// | 
| Misha Brukman | 0e0a7a45 | 2005-04-21 23:38:14 +0000 | [diff] [blame] | 2 | // | 
| John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file was developed by the LLVM research group and is distributed under | 
 | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
| Misha Brukman | 0e0a7a45 | 2005-04-21 23:38:14 +0000 | [diff] [blame] | 7 | // | 
| John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 7261408 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 9 | // | 
| Chris Lattner | b36cbd0 | 2005-07-01 22:44:09 +0000 | [diff] [blame] | 10 | // This file the shared super class printer that converts from our internal | 
 | 11 | // representation of machine-dependent LLVM code to Intel and AT&T format | 
 | 12 | // assembly language. | 
 | 13 | // This printer is the output mechanism used by `llc'. | 
| Chris Lattner | 7261408 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 14 | // | 
 | 15 | //===----------------------------------------------------------------------===// | 
 | 16 |  | 
| Evan Cheng | c4c6257 | 2006-03-13 23:20:37 +0000 | [diff] [blame] | 17 | #include "X86AsmPrinter.h" | 
| Chris Lattner | b36cbd0 | 2005-07-01 22:44:09 +0000 | [diff] [blame] | 18 | #include "X86ATTAsmPrinter.h" | 
| Anton Korobeynikov | d05ca65 | 2007-01-16 16:41:57 +0000 | [diff] [blame] | 19 | #include "X86COFF.h" | 
| Chris Lattner | b36cbd0 | 2005-07-01 22:44:09 +0000 | [diff] [blame] | 20 | #include "X86IntelAsmPrinter.h" | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 21 | #include "X86MachineFunctionInfo.h" | 
| Chris Lattner | a35a8e8 | 2005-11-21 22:39:40 +0000 | [diff] [blame] | 22 | #include "X86Subtarget.h" | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 23 | #include "llvm/ADT/StringExtras.h" | 
 | 24 | #include "llvm/CallingConv.h" | 
| Chris Lattner | a046e0d | 2005-12-13 04:53:51 +0000 | [diff] [blame] | 25 | #include "llvm/Constants.h" | 
| Chris Lattner | d59414f | 2003-08-11 20:06:16 +0000 | [diff] [blame] | 26 | #include "llvm/Module.h" | 
| Chris Lattner | c41cc83 | 2005-11-21 06:46:22 +0000 | [diff] [blame] | 27 | #include "llvm/Type.h" | 
| Chris Lattner | d59414f | 2003-08-11 20:06:16 +0000 | [diff] [blame] | 28 | #include "llvm/Assembly/Writer.h" | 
| Brian Gaeke | d9fb37a | 2003-07-24 20:20:44 +0000 | [diff] [blame] | 29 | #include "llvm/Support/Mangler.h" | 
| Jim Laskey | a0f3d17 | 2006-09-07 22:06:40 +0000 | [diff] [blame] | 30 | #include "llvm/Target/TargetAsmInfo.h" | 
| Anton Korobeynikov | 5032e5a | 2007-01-17 10:33:08 +0000 | [diff] [blame] | 31 | #include "llvm/Target/TargetOptions.h" | 
| Chris Lattner | 300d0ed | 2004-02-14 06:00:36 +0000 | [diff] [blame] | 32 | using namespace llvm; | 
| Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 33 |  | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 34 | static X86FunctionInfo calculateFunctionInfo(const Function *F, | 
 | 35 |                                              const TargetData *TD) { | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 36 |   X86FunctionInfo Info; | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 37 |   uint64_t Size = 0; | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 38 |    | 
 | 39 |   switch (F->getCallingConv()) { | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 40 |   case CallingConv::X86_StdCall: | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 41 |     Info.setDecorationStyle(StdCall); | 
 | 42 |     break; | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 43 |   case CallingConv::X86_FastCall: | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 44 |     Info.setDecorationStyle(FastCall); | 
 | 45 |     break; | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 46 |   default: | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 47 |     return Info; | 
 | 48 |   } | 
 | 49 |  | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 50 |   for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); | 
 | 51 |        AI != AE; ++AI) | 
 | 52 |     Size += TD->getTypeSize(AI->getType()); | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 53 |  | 
| Anton Korobeynikov | 54b1cc6 | 2006-10-14 20:53:35 +0000 | [diff] [blame] | 54 |   // Size should be aligned to DWORD boundary | 
 | 55 |   Size = ((Size + 3)/4)*4; | 
 | 56 |    | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 57 |   // We're not supporting tooooo huge arguments :) | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 58 |   Info.setBytesToPopOnReturn((unsigned int)Size); | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 59 |   return Info; | 
 | 60 | } | 
 | 61 |  | 
 | 62 |  | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 63 | /// decorateName - Query FunctionInfoMap and use this information for various | 
 | 64 | /// name decoration. | 
 | 65 | void X86SharedAsmPrinter::decorateName(std::string &Name, | 
 | 66 |                                        const GlobalValue *GV) { | 
 | 67 |   const Function *F = dyn_cast<Function>(GV); | 
 | 68 |   if (!F) return; | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 69 |  | 
 | 70 |   // We don't want to decorate non-stdcall or non-fastcall functions right now | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 71 |   unsigned CC = F->getCallingConv(); | 
 | 72 |   if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall) | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 73 |     return; | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 74 |      | 
 | 75 |   FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F); | 
 | 76 |  | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 77 |   const X86FunctionInfo *Info; | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 78 |   if (info_item == FunctionInfoMap.end()) { | 
 | 79 |     // Calculate apropriate function info and populate map | 
 | 80 |     FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData()); | 
 | 81 |     Info = &FunctionInfoMap[F]; | 
 | 82 |   } else { | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 83 |     Info = &info_item->second; | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 84 |   } | 
 | 85 |          | 
 | 86 |   switch (Info->getDecorationStyle()) { | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 87 |   case None: | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 88 |     break; | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 89 |   case StdCall: | 
 | 90 |     if (!F->isVarArg()) // Variadic functions do not receive @0 suffix. | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 91 |       Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 92 |     break; | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 93 |   case FastCall: | 
 | 94 |     if (!F->isVarArg()) // Variadic functions do not receive @0 suffix. | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 95 |       Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 96 |  | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 97 |     if (Name[0] == '_') { | 
 | 98 |       Name[0] = '@'; | 
 | 99 |     } else { | 
 | 100 |       Name = '@' + Name; | 
 | 101 |     }     | 
 | 102 |     break; | 
| Chris Lattner | e87e115 | 2006-09-26 03:57:53 +0000 | [diff] [blame] | 103 |   default: | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 104 |     assert(0 && "Unsupported DecorationStyle"); | 
 | 105 |   } | 
| Anton Korobeynikov | f824868 | 2006-09-20 22:03:51 +0000 | [diff] [blame] | 106 | } | 
 | 107 |  | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 108 | /// doInitialization | 
| Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 109 | bool X86SharedAsmPrinter::doInitialization(Module &M) { | 
| Anton Korobeynikov | 7f70559 | 2007-01-12 19:20:47 +0000 | [diff] [blame] | 110 |   if (Subtarget->isTargetELF() || | 
 | 111 |       Subtarget->isTargetCygMing() || | 
 | 112 |       Subtarget->isTargetDarwin()) { | 
| Reid Spencer | 02b8511 | 2006-10-30 22:32:30 +0000 | [diff] [blame] | 113 |     // Emit initial debug information. | 
 | 114 |     DW.BeginModule(&M); | 
| Evan Cheng | d594881 | 2006-03-07 02:23:26 +0000 | [diff] [blame] | 115 |   } | 
| Evan Cheng | 3c992d2 | 2006-03-07 02:02:57 +0000 | [diff] [blame] | 116 |  | 
| Reid Spencer | 5dc81f6 | 2005-01-23 03:52:14 +0000 | [diff] [blame] | 117 |   return AsmPrinter::doInitialization(M); | 
 | 118 | } | 
 | 119 |  | 
| Chris Lattner | ac5701c | 2004-10-04 07:24:48 +0000 | [diff] [blame] | 120 | bool X86SharedAsmPrinter::doFinalization(Module &M) { | 
| Jeff Cohen | d43b18d | 2006-05-06 21:27:14 +0000 | [diff] [blame] | 121 |   // Note: this code is not shared by the Intel printer as it is too different | 
 | 122 |   // from how MASM does things.  When making changes here don't forget to look | 
 | 123 |   // at X86IntelAsmPrinter::doFinalization(). | 
| Owen Anderson | a69571c | 2006-05-03 01:29:57 +0000 | [diff] [blame] | 124 |   const TargetData *TD = TM.getTargetData(); | 
| Anton Korobeynikov | 78ee7b7 | 2006-12-01 00:25:12 +0000 | [diff] [blame] | 125 |    | 
| Chris Lattner | ac5701c | 2004-10-04 07:24:48 +0000 | [diff] [blame] | 126 |   // Print out module-level global variables here. | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 127 |   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); | 
 | 128 |        I != E; ++I) { | 
| Rafael Espindola | 3e69a7e | 2006-12-09 23:14:08 +0000 | [diff] [blame] | 129 |     if (!I->hasInitializer()) | 
| Anton Korobeynikov | 78ee7b7 | 2006-12-01 00:25:12 +0000 | [diff] [blame] | 130 |       continue;   // External global require no code | 
| Chris Lattner | 9787c64 | 2005-11-21 22:48:18 +0000 | [diff] [blame] | 131 |      | 
| Chris Lattner | d1239b7 | 2005-12-13 06:32:50 +0000 | [diff] [blame] | 132 |     // Check to see if this is a special global used by LLVM, if so, emit it. | 
| Jim Laskey | 7809811 | 2006-03-07 22:00:35 +0000 | [diff] [blame] | 133 |     if (EmitSpecialLLVMGlobal(I)) | 
| Chris Lattner | d1239b7 | 2005-12-13 06:32:50 +0000 | [diff] [blame] | 134 |       continue; | 
| Chris Lattner | a046e0d | 2005-12-13 04:53:51 +0000 | [diff] [blame] | 135 |      | 
| Chris Lattner | 9787c64 | 2005-11-21 22:48:18 +0000 | [diff] [blame] | 136 |     std::string name = Mang->getValueName(I); | 
 | 137 |     Constant *C = I->getInitializer(); | 
| Owen Anderson | a69571c | 2006-05-03 01:29:57 +0000 | [diff] [blame] | 138 |     unsigned Size = TD->getTypeSize(C->getType()); | 
| Devang Patel | f9c197e | 2006-10-24 20:32:14 +0000 | [diff] [blame] | 139 |     unsigned Align = TD->getPreferredAlignmentLog(I); | 
| Jeff Cohen | 00b16889 | 2005-07-27 06:12:32 +0000 | [diff] [blame] | 140 |  | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 141 |     if (C->isNullValue() && /* FIXME: Verify correct */ | 
| Evan Cheng | 2e323aa | 2006-10-31 01:26:55 +0000 | [diff] [blame] | 142 |         !I->hasSection() && | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 143 |         (I->hasInternalLinkage() || I->hasWeakLinkage() || | 
| Evan Cheng | 17ef92e | 2006-02-15 01:56:23 +0000 | [diff] [blame] | 144 |          I->hasLinkOnceLinkage() || | 
| Jim Laskey | ea34858 | 2006-07-27 02:05:13 +0000 | [diff] [blame] | 145 |          (Subtarget->isTargetDarwin() &&  | 
| Evan Cheng | 2e323aa | 2006-10-31 01:26:55 +0000 | [diff] [blame] | 146 |           I->hasExternalLinkage()))) { | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 147 |       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it. | 
| Evan Cheng | 17ef92e | 2006-02-15 01:56:23 +0000 | [diff] [blame] | 148 |       if (I->hasExternalLinkage()) { | 
| Evan Cheng | a0ea053 | 2006-02-23 02:43:52 +0000 | [diff] [blame] | 149 |           O << "\t.globl\t" << name << "\n"; | 
| Evan Cheng | 17ef92e | 2006-02-15 01:56:23 +0000 | [diff] [blame] | 150 |           O << "\t.zerofill __DATA__, __common, " << name << ", " | 
 | 151 |             << Size << ", " << Align; | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 152 |       } else { | 
| Anton Korobeynikov | 5032e5a | 2007-01-17 10:33:08 +0000 | [diff] [blame] | 153 |         if (!NoZerosInBSS && TAI->getBSSSection()) | 
 | 154 |           SwitchToDataSection(TAI->getBSSSection(), I); | 
 | 155 |         else | 
 | 156 |           SwitchToDataSection(TAI->getDataSection(), I); | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 157 |         if (TAI->getLCOMMDirective() != NULL) { | 
| Evan Cheng | 17ef92e | 2006-02-15 01:56:23 +0000 | [diff] [blame] | 158 |           if (I->hasInternalLinkage()) { | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 159 |             O << TAI->getLCOMMDirective() << name << "," << Size; | 
| Jim Laskey | ea34858 | 2006-07-27 02:05:13 +0000 | [diff] [blame] | 160 |             if (Subtarget->isTargetDarwin()) | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 161 |               O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); | 
| Evan Cheng | 17ef92e | 2006-02-15 01:56:23 +0000 | [diff] [blame] | 162 |           } else | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 163 |             O << TAI->getCOMMDirective()  << name << "," << Size; | 
| Evan Cheng | 17ef92e | 2006-02-15 01:56:23 +0000 | [diff] [blame] | 164 |         } else { | 
| Anton Korobeynikov | 317848f | 2007-01-03 11:43:14 +0000 | [diff] [blame] | 165 |           if (!Subtarget->isTargetCygMing()) { | 
| Evan Cheng | 932ad51 | 2006-05-25 21:59:08 +0000 | [diff] [blame] | 166 |             if (I->hasInternalLinkage()) | 
 | 167 |               O << "\t.local\t" << name << "\n"; | 
 | 168 |           } | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 169 |           O << TAI->getCOMMDirective()  << name << "," << Size; | 
 | 170 |           if (TAI->getCOMMDirectiveTakesAlignment()) | 
 | 171 |             O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); | 
| Evan Cheng | 17ef92e | 2006-02-15 01:56:23 +0000 | [diff] [blame] | 172 |         } | 
| Chris Lattner | b12c9fa | 2005-07-11 06:25:47 +0000 | [diff] [blame] | 173 |       } | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 174 |       O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n"; | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 175 |     } else { | 
 | 176 |       switch (I->getLinkage()) { | 
 | 177 |       case GlobalValue::LinkOnceLinkage: | 
 | 178 |       case GlobalValue::WeakLinkage: | 
| Jim Laskey | ea34858 | 2006-07-27 02:05:13 +0000 | [diff] [blame] | 179 |         if (Subtarget->isTargetDarwin()) { | 
| Evan Cheng | 5ada370 | 2006-02-07 23:32:58 +0000 | [diff] [blame] | 180 |           O << "\t.globl " << name << "\n" | 
 | 181 |             << "\t.weak_definition " << name << "\n"; | 
| Evan Cheng | f8614db | 2006-06-04 07:24:07 +0000 | [diff] [blame] | 182 |           SwitchToDataSection(".section __DATA,__const_coal,coalesced", I); | 
| Anton Korobeynikov | 317848f | 2007-01-03 11:43:14 +0000 | [diff] [blame] | 183 |         } else if (Subtarget->isTargetCygMing()) { | 
| Anton Korobeynikov | 1a3ecbb | 2006-10-22 21:37:13 +0000 | [diff] [blame] | 184 |           std::string SectionName(".section\t.data$linkonce." + | 
 | 185 |                                   name + | 
| Evan Cheng | 2e323aa | 2006-10-31 01:26:55 +0000 | [diff] [blame] | 186 |                                   ",\"aw\""); | 
| Anton Korobeynikov | 1a3ecbb | 2006-10-22 21:37:13 +0000 | [diff] [blame] | 187 |           SwitchToDataSection(SectionName.c_str(), I); | 
 | 188 |           O << "\t.globl " << name << "\n" | 
| Anton Korobeynikov | b1c8802 | 2006-10-18 09:12:29 +0000 | [diff] [blame] | 189 |             << "\t.linkonce same_size\n"; | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 190 |         } else { | 
| Anton Korobeynikov | 1a3ecbb | 2006-10-22 21:37:13 +0000 | [diff] [blame] | 191 |           std::string SectionName("\t.section\t.llvm.linkonce.d." + | 
 | 192 |                                   name + | 
| Evan Cheng | 2e323aa | 2006-10-31 01:26:55 +0000 | [diff] [blame] | 193 |                                   ",\"aw\",@progbits"); | 
| Anton Korobeynikov | 1a3ecbb | 2006-10-22 21:37:13 +0000 | [diff] [blame] | 194 |           SwitchToDataSection(SectionName.c_str(), I); | 
 | 195 |           O << "\t.weak " << name << "\n"; | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 196 |         } | 
 | 197 |         break; | 
 | 198 |       case GlobalValue::AppendingLinkage: | 
 | 199 |         // FIXME: appending linkage variables should go into a section of | 
 | 200 |         // their name or something.  For now, just emit them as external. | 
| Anton Korobeynikov | b74ed07 | 2006-09-14 18:23:27 +0000 | [diff] [blame] | 201 |       case GlobalValue::DLLExportLinkage: | 
 | 202 |         DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),"")); | 
 | 203 |         // FALL THROUGH | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 204 |       case GlobalValue::ExternalLinkage: | 
 | 205 |         // If external or appending, declare as a global symbol | 
 | 206 |         O << "\t.globl " << name << "\n"; | 
 | 207 |         // FALL THROUGH | 
| Evan Cheng | 8910c1c | 2006-10-26 19:18:18 +0000 | [diff] [blame] | 208 |       case GlobalValue::InternalLinkage: { | 
| Evan Cheng | 71aae62 | 2006-10-28 05:56:06 +0000 | [diff] [blame] | 209 |         if (I->isConstant()) { | 
| Evan Cheng | 8910c1c | 2006-10-26 19:18:18 +0000 | [diff] [blame] | 210 |           const ConstantArray *CVA = dyn_cast<ConstantArray>(C); | 
| Evan Cheng | 71aae62 | 2006-10-28 05:56:06 +0000 | [diff] [blame] | 211 |           if (TAI->getCStringSection() && CVA && CVA->isCString()) { | 
| Evan Cheng | 8910c1c | 2006-10-26 19:18:18 +0000 | [diff] [blame] | 212 |             SwitchToDataSection(TAI->getCStringSection(), I); | 
 | 213 |             break; | 
 | 214 |           } | 
 | 215 |         } | 
| Evan Cheng | 2e323aa | 2006-10-31 01:26:55 +0000 | [diff] [blame] | 216 |         // FIXME: special handling for ".ctors" & ".dtors" sections | 
 | 217 |         if (I->hasSection() && | 
 | 218 |             (I->getSection() == ".ctors" || | 
 | 219 |              I->getSection() == ".dtors")) { | 
 | 220 |           std::string SectionName = ".section " + I->getSection(); | 
 | 221 |            | 
| Anton Korobeynikov | 317848f | 2007-01-03 11:43:14 +0000 | [diff] [blame] | 222 |           if (Subtarget->isTargetCygMing()) { | 
| Evan Cheng | 2e323aa | 2006-10-31 01:26:55 +0000 | [diff] [blame] | 223 |             SectionName += ",\"aw\""; | 
 | 224 |           } else { | 
 | 225 |             assert(!Subtarget->isTargetDarwin()); | 
 | 226 |             SectionName += ",\"aw\",@progbits"; | 
 | 227 |           } | 
 | 228 |  | 
| Anton Korobeynikov | b52cf1f | 2006-10-31 06:11:06 +0000 | [diff] [blame] | 229 |           SwitchToDataSection(SectionName.c_str()); | 
| Evan Cheng | 2e323aa | 2006-10-31 01:26:55 +0000 | [diff] [blame] | 230 |         } else { | 
| Anton Korobeynikov | 5032e5a | 2007-01-17 10:33:08 +0000 | [diff] [blame] | 231 |           if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection()) | 
 | 232 |             SwitchToDataSection(TAI->getBSSSection(), I); | 
 | 233 |           else | 
 | 234 |             SwitchToDataSection(TAI->getDataSection(), I); | 
| Evan Cheng | 2e323aa | 2006-10-31 01:26:55 +0000 | [diff] [blame] | 235 |         } | 
 | 236 |          | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 237 |         break; | 
| Evan Cheng | 8910c1c | 2006-10-26 19:18:18 +0000 | [diff] [blame] | 238 |       } | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 239 |       default: | 
 | 240 |         assert(0 && "Unknown linkage type!"); | 
 | 241 |       } | 
| Chris Lattner | 9787c64 | 2005-11-21 22:48:18 +0000 | [diff] [blame] | 242 |  | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 243 |       EmitAlignment(Align, I); | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 244 |       O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName() | 
| Evan Cheng | 5ada370 | 2006-02-07 23:32:58 +0000 | [diff] [blame] | 245 |         << "\n"; | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 246 |       if (TAI->hasDotTypeDotSizeDirective()) | 
| Evan Cheng | 5ada370 | 2006-02-07 23:32:58 +0000 | [diff] [blame] | 247 |         O << "\t.size " << name << ", " << Size << "\n"; | 
| Evan Cheng | 81cf60f | 2006-12-01 09:13:26 +0000 | [diff] [blame] | 248 |       // If the initializer is a extern weak symbol, remember to emit the weak | 
 | 249 |       // reference! | 
 | 250 |       if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) | 
 | 251 |         if (GV->hasExternalWeakLinkage()) | 
| Rafael Espindola | 15404d0 | 2006-12-18 03:37:18 +0000 | [diff] [blame] | 252 |           ExtWeakSymbols.insert(GV); | 
| Evan Cheng | 81cf60f | 2006-12-01 09:13:26 +0000 | [diff] [blame] | 253 |  | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 254 |       EmitGlobalConstant(C); | 
 | 255 |       O << '\n'; | 
| Chris Lattner | 9787c64 | 2005-11-21 22:48:18 +0000 | [diff] [blame] | 256 |     } | 
| Chris Lattner | 43bbc5c | 2007-01-14 06:29:53 +0000 | [diff] [blame] | 257 |     if (I->hasHiddenVisibility()) | 
 | 258 |       if (const char *Directive = TAI->getHiddenDirective()) | 
 | 259 |         O << Directive << name << "\n"; | 
| Anton Korobeynikov | d05ca65 | 2007-01-16 16:41:57 +0000 | [diff] [blame] | 260 |      | 
 | 261 |     if (Subtarget->isTargetELF()) | 
 | 262 |       O << "\t.type " << name << ",@object\n"; | 
| Chris Lattner | a35a8e8 | 2005-11-21 22:39:40 +0000 | [diff] [blame] | 263 |   } | 
 | 264 |    | 
| Anton Korobeynikov | b74ed07 | 2006-09-14 18:23:27 +0000 | [diff] [blame] | 265 |   // Output linker support code for dllexported globals | 
 | 266 |   if (DLLExportedGVs.begin() != DLLExportedGVs.end()) { | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 267 |     SwitchToDataSection(".section .drectve"); | 
| Anton Korobeynikov | b74ed07 | 2006-09-14 18:23:27 +0000 | [diff] [blame] | 268 |   } | 
 | 269 |  | 
 | 270 |   for (std::set<std::string>::iterator i = DLLExportedGVs.begin(), | 
 | 271 |          e = DLLExportedGVs.end(); | 
 | 272 |          i != e; ++i) { | 
 | 273 |     O << "\t.ascii \" -export:" << *i << ",data\"\n"; | 
 | 274 |   }     | 
 | 275 |  | 
 | 276 |   if (DLLExportedFns.begin() != DLLExportedFns.end()) { | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 277 |     SwitchToDataSection(".section .drectve"); | 
| Anton Korobeynikov | b74ed07 | 2006-09-14 18:23:27 +0000 | [diff] [blame] | 278 |   } | 
 | 279 |  | 
 | 280 |   for (std::set<std::string>::iterator i = DLLExportedFns.begin(), | 
 | 281 |          e = DLLExportedFns.end(); | 
 | 282 |          i != e; ++i) { | 
 | 283 |     O << "\t.ascii \" -export:" << *i << "\"\n"; | 
 | 284 |   }     | 
| Anton Korobeynikov | 78ee7b7 | 2006-12-01 00:25:12 +0000 | [diff] [blame] | 285 |  | 
| Jim Laskey | ea34858 | 2006-07-27 02:05:13 +0000 | [diff] [blame] | 286 |   if (Subtarget->isTargetDarwin()) { | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 287 |     SwitchToDataSection(""); | 
| Nate Begeman | 73213f6 | 2005-07-12 01:37:28 +0000 | [diff] [blame] | 288 |  | 
| Nate Begeman | 72b286b | 2005-07-08 00:23:26 +0000 | [diff] [blame] | 289 |     // Output stubs for dynamically-linked functions | 
 | 290 |     unsigned j = 1; | 
 | 291 |     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); | 
| Chris Lattner | b12c9fa | 2005-07-11 06:25:47 +0000 | [diff] [blame] | 292 |          i != e; ++i, ++j) { | 
| Chris Lattner | 4632d7a | 2006-05-09 04:59:56 +0000 | [diff] [blame] | 293 |       SwitchToDataSection(".section __IMPORT,__jump_table,symbol_stubs," | 
 | 294 |                           "self_modifying_code+pure_instructions,5", 0); | 
| Nate Begeman | 72b286b | 2005-07-08 00:23:26 +0000 | [diff] [blame] | 295 |       O << "L" << *i << "$stub:\n"; | 
 | 296 |       O << "\t.indirect_symbol " << *i << "\n"; | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 297 |       O << "\thlt ; hlt ; hlt ; hlt ; hlt\n"; | 
| Nate Begeman | 72b286b | 2005-07-08 00:23:26 +0000 | [diff] [blame] | 298 |     } | 
 | 299 |  | 
 | 300 |     O << "\n"; | 
| Jeff Cohen | 00b16889 | 2005-07-27 06:12:32 +0000 | [diff] [blame] | 301 |  | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 302 |     // Output stubs for external and common global variables. | 
 | 303 |     if (GVStubs.begin() != GVStubs.end()) | 
| Chris Lattner | 4632d7a | 2006-05-09 04:59:56 +0000 | [diff] [blame] | 304 |       SwitchToDataSection( | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 305 |                     ".section __IMPORT,__pointers,non_lazy_symbol_pointers"); | 
| Evan Cheng | 2338c5c | 2006-02-07 08:38:37 +0000 | [diff] [blame] | 306 |     for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end(); | 
 | 307 |          i != e; ++i) { | 
 | 308 |       O << "L" << *i << "$non_lazy_ptr:\n"; | 
 | 309 |       O << "\t.indirect_symbol " << *i << "\n"; | 
 | 310 |       O << "\t.long\t0\n"; | 
| Nate Begeman | 72b286b | 2005-07-08 00:23:26 +0000 | [diff] [blame] | 311 |     } | 
| Chris Lattner | ac5701c | 2004-10-04 07:24:48 +0000 | [diff] [blame] | 312 |  | 
| Reid Spencer | 02b8511 | 2006-10-30 22:32:30 +0000 | [diff] [blame] | 313 |     // Emit final debug information. | 
| Jim Laskey | 99db044 | 2006-03-23 18:09:44 +0000 | [diff] [blame] | 314 |     DW.EndModule(); | 
| Evan Cheng | d594881 | 2006-03-07 02:23:26 +0000 | [diff] [blame] | 315 |  | 
 | 316 |     // Funny Darwin hack: This flag tells the linker that no global symbols | 
 | 317 |     // contain code that falls through to other global symbols (e.g. the obvious | 
 | 318 |     // implementation of multiple entry points).  If this doesn't occur, the | 
| Jim Laskey | 99db044 | 2006-03-23 18:09:44 +0000 | [diff] [blame] | 319 |     // linker can safely perform dead code stripping.  Since LLVM never | 
 | 320 |     // generates code that does this, it is always safe to set. | 
| Evan Cheng | d594881 | 2006-03-07 02:23:26 +0000 | [diff] [blame] | 321 |     O << "\t.subsections_via_symbols\n"; | 
| Anton Korobeynikov | d05ca65 | 2007-01-16 16:41:57 +0000 | [diff] [blame] | 322 |   } else if (Subtarget->isTargetCygMing()) { | 
 | 323 |     // Emit type information for external functions | 
 | 324 |     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); | 
 | 325 |          i != e; ++i) { | 
 | 326 |       O << "\t.def\t " << *i | 
 | 327 |         << ";\t.scl\t" << COFF::C_EXT | 
 | 328 |         << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT) | 
 | 329 |         << ";\t.endef\n"; | 
 | 330 |     } | 
 | 331 |      | 
 | 332 |     // Emit final debug information. | 
 | 333 |     DW.EndModule();     | 
 | 334 |   } else if (Subtarget->isTargetELF()) { | 
| Reid Spencer | 02b8511 | 2006-10-30 22:32:30 +0000 | [diff] [blame] | 335 |     // Emit final debug information. | 
 | 336 |     DW.EndModule(); | 
| Evan Cheng | d594881 | 2006-03-07 02:23:26 +0000 | [diff] [blame] | 337 |   } | 
| Evan Cheng | 3c992d2 | 2006-03-07 02:02:57 +0000 | [diff] [blame] | 338 |  | 
| Chris Lattner | ac5701c | 2004-10-04 07:24:48 +0000 | [diff] [blame] | 339 |   AsmPrinter::doFinalization(M); | 
 | 340 |   return false; // success | 
 | 341 | } | 
 | 342 |  | 
| Chris Lattner | ac5701c | 2004-10-04 07:24:48 +0000 | [diff] [blame] | 343 | /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code | 
 | 344 | /// for a MachineFunction to the given output stream, using the given target | 
 | 345 | /// machine description. | 
 | 346 | /// | 
| Evan Cheng | c4c6257 | 2006-03-13 23:20:37 +0000 | [diff] [blame] | 347 | FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o, | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 348 |                                              X86TargetMachine &tm) { | 
| Jim Laskey | 05a059d | 2006-09-07 12:23:47 +0000 | [diff] [blame] | 349 |   const X86Subtarget *Subtarget = &tm.getSubtarget<X86Subtarget>(); | 
| Jim Laskey | 563321a | 2006-09-06 18:34:40 +0000 | [diff] [blame] | 350 |  | 
| Jim Laskey | 05a059d | 2006-09-07 12:23:47 +0000 | [diff] [blame] | 351 |   if (Subtarget->isFlavorIntel()) { | 
| Jim Laskey | a0f3d17 | 2006-09-07 22:06:40 +0000 | [diff] [blame] | 352 |     return new X86IntelAsmPrinter(o, tm, tm.getTargetAsmInfo()); | 
| Jim Laskey | 05a059d | 2006-09-07 12:23:47 +0000 | [diff] [blame] | 353 |   } else { | 
| Jim Laskey | a0f3d17 | 2006-09-07 22:06:40 +0000 | [diff] [blame] | 354 |     return new X86ATTAsmPrinter(o, tm, tm.getTargetAsmInfo()); | 
| Chris Lattner | ac5701c | 2004-10-04 07:24:48 +0000 | [diff] [blame] | 355 |   } | 
| Brian Gaeke | 9e474c4 | 2003-06-19 19:32:32 +0000 | [diff] [blame] | 356 | } |