| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 1 | //===-- DarwinTargetAsmInfo.cpp - Darwin asm properties ---------*- C++ -*-===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
 | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // This file defines target asm properties related what form asm statements | 
 | 11 | // should take in general on Darwin-based targets | 
 | 12 | // | 
 | 13 | //===----------------------------------------------------------------------===// | 
 | 14 |  | 
 | 15 | #include "llvm/Constants.h" | 
 | 16 | #include "llvm/DerivedTypes.h" | 
 | 17 | #include "llvm/Function.h" | 
 | 18 | #include "llvm/GlobalVariable.h" | 
 | 19 | #include "llvm/ADT/StringExtras.h" | 
| Dale Johannesen | d2e51af | 2008-09-09 22:29:13 +0000 | [diff] [blame] | 20 | #include "llvm/Support/Mangler.h" | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 21 | #include "llvm/Target/DarwinTargetAsmInfo.h" | 
 | 22 | #include "llvm/Target/TargetMachine.h" | 
 | 23 | #include "llvm/Target/TargetData.h" | 
 | 24 |  | 
 | 25 | using namespace llvm; | 
 | 26 |  | 
 | 27 | DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) { | 
| Anton Korobeynikov | 18f6ed9 | 2008-07-19 13:15:21 +0000 | [diff] [blame] | 28 |   DTM = &TM; | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 29 |  | 
 | 30 |   CStringSection_ = getUnnamedSection("\t.cstring", | 
 | 31 |                                 SectionFlags::Mergeable | SectionFlags::Strings); | 
| Anton Korobeynikov | 6481873 | 2008-09-24 22:18:54 +0000 | [diff] [blame] | 32 |   FourByteConstantSection = getUnnamedSection("\t.literal4\n", | 
 | 33 |                                               SectionFlags::Mergeable); | 
 | 34 |   EightByteConstantSection = getUnnamedSection("\t.literal8\n", | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 35 |                                                SectionFlags::Mergeable); | 
| Anton Korobeynikov | ae408e6 | 2008-07-19 13:16:11 +0000 | [diff] [blame] | 36 |  | 
| Anton Korobeynikov | cff2ea0 | 2008-07-19 13:15:46 +0000 | [diff] [blame] | 37 |   // Note: 16-byte constant section is subtarget specific and should be provided | 
| Anton Korobeynikov | 6481873 | 2008-09-24 22:18:54 +0000 | [diff] [blame] | 38 |   // there, if needed. | 
 | 39 |   SixteenByteConstantSection = 0; | 
| Anton Korobeynikov | cff2ea0 | 2008-07-19 13:15:46 +0000 | [diff] [blame] | 40 |  | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 41 |   ReadOnlySection_ = getUnnamedSection("\t.const\n", SectionFlags::None); | 
 | 42 |  | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 43 |   TextCoalSection = | 
| Anton Korobeynikov | d79cda9 | 2008-09-24 22:19:13 +0000 | [diff] [blame^] | 44 |     getNamedSection("\t__TEXT,__textcoal_nt,coalesced,pure_instructions", | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 45 |                     SectionFlags::Code); | 
| Anton Korobeynikov | d79cda9 | 2008-09-24 22:19:13 +0000 | [diff] [blame^] | 46 |   ConstDataCoalSection = getBamedSection("\t__DATA,__const_coal,coalesced", | 
 | 47 |                                          SectionFlags::None); | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 48 |   ConstDataSection = getUnnamedSection(".const_data", SectionFlags::None); | 
| Anton Korobeynikov | d79cda9 | 2008-09-24 22:19:13 +0000 | [diff] [blame^] | 49 |   DataCoalSection = getNamedSection("\t__DATA,__datacoal_nt,coalesced", | 
 | 50 |                                     SectionFlags::Writeable); | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 51 | } | 
 | 52 |  | 
| Dale Johannesen | d2e51af | 2008-09-09 22:29:13 +0000 | [diff] [blame] | 53 | /// emitUsedDirectiveFor - On Darwin, internally linked data beginning with | 
 | 54 | /// the PrivateGlobalPrefix or the LessPrivateGlobalPrefix does not have the | 
 | 55 | /// directive emitted (this occurs in ObjC metadata). | 
 | 56 |  | 
 | 57 | bool | 
 | 58 | DarwinTargetAsmInfo::emitUsedDirectiveFor(const GlobalValue* GV, | 
 | 59 |                                           Mangler *Mang) const { | 
 | 60 |   if (GV==0) | 
 | 61 |     return false; | 
 | 62 |   if (GV->hasInternalLinkage() && !isa<Function>(GV) && | 
 | 63 |       ((strlen(getPrivateGlobalPrefix()) != 0 && | 
 | 64 |         Mang->getValueName(GV).substr(0,strlen(getPrivateGlobalPrefix())) == | 
 | 65 |           getPrivateGlobalPrefix()) || | 
 | 66 |        (strlen(getLessPrivateGlobalPrefix()) != 0 && | 
 | 67 |         Mang->getValueName(GV).substr(0,strlen(getLessPrivateGlobalPrefix())) == | 
 | 68 |           getLessPrivateGlobalPrefix()))) | 
 | 69 |     return false; | 
 | 70 |   return true; | 
 | 71 | } | 
 | 72 |  | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 73 | const Section* | 
| Evan Cheng | 42ccc21 | 2008-08-08 17:56:50 +0000 | [diff] [blame] | 74 | DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 75 |   SectionKind::Kind Kind = SectionKindForGlobal(GV); | 
| Evan Cheng | 42ccc21 | 2008-08-08 17:56:50 +0000 | [diff] [blame] | 76 |   bool isWeak = GV->isWeakForLinker(); | 
| Anton Korobeynikov | 18f6ed9 | 2008-07-19 13:15:21 +0000 | [diff] [blame] | 77 |   bool isNonStatic = (DTM->getRelocationModel() != Reloc::Static); | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 78 |  | 
 | 79 |   switch (Kind) { | 
 | 80 |    case SectionKind::Text: | 
| Evan Cheng | 42ccc21 | 2008-08-08 17:56:50 +0000 | [diff] [blame] | 81 |     if (isWeak) | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 82 |       return TextCoalSection; | 
 | 83 |     else | 
| Anton Korobeynikov | 0b501d1 | 2008-09-24 22:16:33 +0000 | [diff] [blame] | 84 |       return TextSection; | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 85 |    case SectionKind::Data: | 
 | 86 |    case SectionKind::ThreadData: | 
 | 87 |    case SectionKind::BSS: | 
 | 88 |    case SectionKind::ThreadBSS: | 
 | 89 |     if (cast<GlobalVariable>(GV)->isConstant()) | 
| Evan Cheng | 42ccc21 | 2008-08-08 17:56:50 +0000 | [diff] [blame] | 90 |       return (isWeak ? ConstDataCoalSection : ConstDataSection); | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 91 |     else | 
| Anton Korobeynikov | 0b501d1 | 2008-09-24 22:16:33 +0000 | [diff] [blame] | 92 |       return (isWeak ? DataCoalSection : DataSection); | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 93 |    case SectionKind::ROData: | 
| Evan Cheng | 42ccc21 | 2008-08-08 17:56:50 +0000 | [diff] [blame] | 94 |     return (isWeak ? ConstDataCoalSection : | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 95 |             (isNonStatic ? ConstDataSection : getReadOnlySection_())); | 
 | 96 |    case SectionKind::RODataMergeStr: | 
| Evan Cheng | 42ccc21 | 2008-08-08 17:56:50 +0000 | [diff] [blame] | 97 |     return (isWeak ? | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 98 |             ConstDataCoalSection : | 
 | 99 |             MergeableStringSection(cast<GlobalVariable>(GV))); | 
 | 100 |    case SectionKind::RODataMergeConst: | 
| Evan Cheng | 42ccc21 | 2008-08-08 17:56:50 +0000 | [diff] [blame] | 101 |     return (isWeak ? | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 102 |             ConstDataCoalSection: | 
 | 103 |             MergeableConstSection(cast<GlobalVariable>(GV))); | 
 | 104 |    default: | 
 | 105 |     assert(0 && "Unsuported section kind for global"); | 
 | 106 |   } | 
 | 107 |  | 
 | 108 |   // FIXME: Do we have any extra special weird cases? | 
 | 109 | } | 
 | 110 |  | 
 | 111 | const Section* | 
 | 112 | DarwinTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { | 
| Anton Korobeynikov | 18f6ed9 | 2008-07-19 13:15:21 +0000 | [diff] [blame] | 113 |   const TargetData *TD = DTM->getTargetData(); | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 114 |   Constant *C = cast<GlobalVariable>(GV)->getInitializer(); | 
 | 115 |   const Type *Type = cast<ConstantArray>(C)->getType()->getElementType(); | 
 | 116 |  | 
 | 117 |   unsigned Size = TD->getABITypeSize(Type); | 
 | 118 |   if (Size) { | 
| Anton Korobeynikov | 18f6ed9 | 2008-07-19 13:15:21 +0000 | [diff] [blame] | 119 |     const TargetData *TD = DTM->getTargetData(); | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 120 |     unsigned Align = TD->getPreferredAlignment(GV); | 
 | 121 |     if (Align <= 32) | 
 | 122 |       return getCStringSection_(); | 
 | 123 |   } | 
 | 124 |  | 
 | 125 |   return getReadOnlySection_(); | 
 | 126 | } | 
 | 127 |  | 
 | 128 | const Section* | 
 | 129 | DarwinTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { | 
| Anton Korobeynikov | dbab2d2 | 2008-09-24 22:17:27 +0000 | [diff] [blame] | 130 |   Constant *C = GV->getInitializer(); | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 131 |  | 
| Anton Korobeynikov | 84e160e | 2008-08-07 09:51:02 +0000 | [diff] [blame] | 132 |   return MergeableConstSection(C->getType()); | 
 | 133 | } | 
 | 134 |  | 
 | 135 | inline const Section* | 
 | 136 | DarwinTargetAsmInfo::MergeableConstSection(const Type *Ty) const { | 
 | 137 |   const TargetData *TD = DTM->getTargetData(); | 
 | 138 |  | 
 | 139 |   unsigned Size = TD->getABITypeSize(Ty); | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 140 |   if (Size == 4) | 
| Anton Korobeynikov | 6481873 | 2008-09-24 22:18:54 +0000 | [diff] [blame] | 141 |     return FourByteConstantSection; | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 142 |   else if (Size == 8) | 
| Anton Korobeynikov | 6481873 | 2008-09-24 22:18:54 +0000 | [diff] [blame] | 143 |     return EightByteConstantSection; | 
 | 144 |   else if (Size == 16 && SixteenByteConstantSection) | 
 | 145 |     return SixteenByteConstantSection; | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 146 |  | 
 | 147 |   return getReadOnlySection_(); | 
 | 148 | } | 
 | 149 |  | 
| Anton Korobeynikov | 84e160e | 2008-08-07 09:51:02 +0000 | [diff] [blame] | 150 | const Section* | 
 | 151 | DarwinTargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { | 
 | 152 |   const Section* S = MergeableConstSection(Ty); | 
 | 153 |  | 
 | 154 |   // Handle weird special case, when compiling PIC stuff. | 
 | 155 |   if (S == getReadOnlySection_() && | 
 | 156 |       DTM->getRelocationModel() != Reloc::Static) | 
 | 157 |     return ConstDataSection; | 
 | 158 |  | 
 | 159 |   return S; | 
 | 160 | } | 
 | 161 |  | 
| Anton Korobeynikov | 745e864 | 2008-07-19 13:14:46 +0000 | [diff] [blame] | 162 | std::string | 
 | 163 | DarwinTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV, | 
 | 164 |                                                SectionKind::Kind kind) const { | 
 | 165 |   assert(0 && "Darwin does not use unique sections"); | 
 | 166 |   return ""; | 
 | 167 | } |