1 //===-- AMDGPUTargetStreamer.cpp - Mips Target Streamer Methods -----------===// 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 provides AMDGPU specific target streamer methods. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AMDGPU.h" 15 #include "AMDGPUTargetStreamer.h" 16 #include "SIDefines.h" 17 #include "Utils/AMDGPUBaseInfo.h" 18 #include "Utils/AMDKernelCodeTUtils.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/IR/Constants.h" 21 #include "llvm/IR/Function.h" 22 #include "llvm/IR/Metadata.h" 23 #include "llvm/IR/Module.h" 24 #include "llvm/MC/MCContext.h" 25 #include "llvm/MC/MCELFStreamer.h" 26 #include "llvm/MC/MCObjectFileInfo.h" 27 #include "llvm/MC/MCSectionELF.h" 28 #include "llvm/Support/ELF.h" 29 #include "llvm/Support/FormattedStream.h" 30 31 namespace llvm { 32 #include "AMDGPUPTNote.h" 33 } 34 35 using namespace llvm; 36 using namespace llvm::AMDGPU; 37 38 //===----------------------------------------------------------------------===// 39 // AMDGPUTargetStreamer 40 //===----------------------------------------------------------------------===// 41 42 AMDGPUTargetStreamer::AMDGPUTargetStreamer(MCStreamer &S) 43 : MCTargetStreamer(S) {} 44 45 void AMDGPUTargetStreamer::EmitStartOfCodeObjectMetadata(const Module &Mod) { 46 CodeObjectMetadataStreamer.begin(Mod); 47 } 48 49 void AMDGPUTargetStreamer::EmitKernelCodeObjectMetadata( 50 const Function &Func, const amd_kernel_code_t &KernelCode) { 51 CodeObjectMetadataStreamer.emitKernel(Func, KernelCode); 52 } 53 54 void AMDGPUTargetStreamer::EmitEndOfCodeObjectMetadata() { 55 CodeObjectMetadataStreamer.end(); 56 EmitCodeObjectMetadata(CodeObjectMetadataStreamer.toYamlString().get()); 57 } 58 59 //===----------------------------------------------------------------------===// 60 // AMDGPUTargetAsmStreamer 61 //===----------------------------------------------------------------------===// 62 63 AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S, 64 formatted_raw_ostream &OS) 65 : AMDGPUTargetStreamer(S), OS(OS) { } 66 67 void 68 AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major, 69 uint32_t Minor) { 70 OS << "\t.hsa_code_object_version " << 71 Twine(Major) << "," << Twine(Minor) << '\n'; 72 } 73 74 void 75 AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major, 76 uint32_t Minor, 77 uint32_t Stepping, 78 StringRef VendorName, 79 StringRef ArchName) { 80 OS << "\t.hsa_code_object_isa " << 81 Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) << 82 ",\"" << VendorName << "\",\"" << ArchName << "\"\n"; 83 84 } 85 86 void 87 AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) { 88 OS << "\t.amd_kernel_code_t\n"; 89 dumpAmdKernelCode(&Header, OS, "\t\t"); 90 OS << "\t.end_amd_kernel_code_t\n"; 91 } 92 93 void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName, 94 unsigned Type) { 95 switch (Type) { 96 default: llvm_unreachable("Invalid AMDGPU symbol type"); 97 case ELF::STT_AMDGPU_HSA_KERNEL: 98 OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ; 99 break; 100 } 101 } 102 103 void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaModuleScopeGlobal( 104 StringRef GlobalName) { 105 OS << "\t.amdgpu_hsa_module_global " << GlobalName << '\n'; 106 } 107 108 void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaProgramScopeGlobal( 109 StringRef GlobalName) { 110 OS << "\t.amdgpu_hsa_program_global " << GlobalName << '\n'; 111 } 112 113 bool AMDGPUTargetAsmStreamer::EmitCodeObjectMetadata(StringRef YamlString) { 114 auto VerifiedYamlString = CodeObjectMetadataStreamer.toYamlString(YamlString); 115 if (!VerifiedYamlString) 116 return false; 117 118 OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveBegin << '\n'; 119 OS << VerifiedYamlString.get(); 120 OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveEnd << '\n'; 121 122 return true; 123 } 124 125 //===----------------------------------------------------------------------===// 126 // AMDGPUTargetELFStreamer 127 //===----------------------------------------------------------------------===// 128 129 AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S) 130 : AMDGPUTargetStreamer(S), Streamer(S) {} 131 132 MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() { 133 return static_cast<MCELFStreamer &>(Streamer); 134 } 135 136 void AMDGPUTargetELFStreamer::EmitAMDGPUNote( 137 const MCExpr *DescSZ, ElfNote::NoteType Type, 138 function_ref<void(MCELFStreamer &)> EmitDesc) { 139 auto &S = getStreamer(); 140 auto &Context = S.getContext(); 141 142 auto NameSZ = sizeof(ElfNote::NoteName); 143 144 S.PushSection(); 145 S.SwitchSection(Context.getELFSection( 146 ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC)); 147 S.EmitIntValue(NameSZ, 4); // namesz 148 S.EmitValue(DescSZ, 4); // descz 149 S.EmitIntValue(Type, 4); // type 150 S.EmitBytes(StringRef(ElfNote::NoteName, NameSZ)); // name 151 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0 152 EmitDesc(S); // desc 153 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0 154 S.PopSection(); 155 } 156 157 void 158 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major, 159 uint32_t Minor) { 160 161 EmitAMDGPUNote( 162 MCConstantExpr::create(8, getContext()), 163 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION, 164 [&](MCELFStreamer &OS){ 165 OS.EmitIntValue(Major, 4); 166 OS.EmitIntValue(Minor, 4); 167 } 168 ); 169 } 170 171 void 172 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major, 173 uint32_t Minor, 174 uint32_t Stepping, 175 StringRef VendorName, 176 StringRef ArchName) { 177 uint16_t VendorNameSize = VendorName.size() + 1; 178 uint16_t ArchNameSize = ArchName.size() + 1; 179 180 unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) + 181 sizeof(Major) + sizeof(Minor) + sizeof(Stepping) + 182 VendorNameSize + ArchNameSize; 183 184 EmitAMDGPUNote( 185 MCConstantExpr::create(DescSZ, getContext()), 186 ElfNote::NT_AMDGPU_HSA_ISA, 187 [&](MCELFStreamer &OS) { 188 OS.EmitIntValue(VendorNameSize, 2); 189 OS.EmitIntValue(ArchNameSize, 2); 190 OS.EmitIntValue(Major, 4); 191 OS.EmitIntValue(Minor, 4); 192 OS.EmitIntValue(Stepping, 4); 193 OS.EmitBytes(VendorName); 194 OS.EmitIntValue(0, 1); // NULL terminate VendorName 195 OS.EmitBytes(ArchName); 196 OS.EmitIntValue(0, 1); // NULL terminte ArchName 197 } 198 ); 199 } 200 201 void 202 AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) { 203 204 MCStreamer &OS = getStreamer(); 205 OS.PushSection(); 206 OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header))); 207 OS.PopSection(); 208 } 209 210 void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName, 211 unsigned Type) { 212 MCSymbolELF *Symbol = cast<MCSymbolELF>( 213 getStreamer().getContext().getOrCreateSymbol(SymbolName)); 214 Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL); 215 } 216 217 void AMDGPUTargetELFStreamer::EmitAMDGPUHsaModuleScopeGlobal( 218 StringRef GlobalName) { 219 220 MCSymbolELF *Symbol = cast<MCSymbolELF>( 221 getStreamer().getContext().getOrCreateSymbol(GlobalName)); 222 Symbol->setType(ELF::STT_OBJECT); 223 Symbol->setBinding(ELF::STB_LOCAL); 224 } 225 226 void AMDGPUTargetELFStreamer::EmitAMDGPUHsaProgramScopeGlobal( 227 StringRef GlobalName) { 228 229 MCSymbolELF *Symbol = cast<MCSymbolELF>( 230 getStreamer().getContext().getOrCreateSymbol(GlobalName)); 231 Symbol->setType(ELF::STT_OBJECT); 232 Symbol->setBinding(ELF::STB_GLOBAL); 233 } 234 235 bool AMDGPUTargetELFStreamer::EmitCodeObjectMetadata(StringRef YamlString) { 236 auto VerifiedYamlString = CodeObjectMetadataStreamer.toYamlString(YamlString); 237 if (!VerifiedYamlString) 238 return false; 239 240 // Create two labels to mark the beginning and end of the desc field 241 // and a MCExpr to calculate the size of the desc field. 242 auto &Context = getContext(); 243 auto *DescBegin = Context.createTempSymbol(); 244 auto *DescEnd = Context.createTempSymbol(); 245 auto *DescSZ = MCBinaryExpr::createSub( 246 MCSymbolRefExpr::create(DescEnd, Context), 247 MCSymbolRefExpr::create(DescBegin, Context), Context); 248 249 EmitAMDGPUNote( 250 DescSZ, 251 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_METADATA, 252 [&](MCELFStreamer &OS) { 253 OS.EmitLabel(DescBegin); 254 OS.EmitBytes(VerifiedYamlString.get()); 255 OS.EmitLabel(DescEnd); 256 } 257 ); 258 259 return true; 260 } 261