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 "AMDGPUTargetStreamer.h" 15 #include "AMDGPU.h" 16 #include "SIDefines.h" 17 #include "Utils/AMDGPUBaseInfo.h" 18 #include "Utils/AMDKernelCodeTUtils.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/BinaryFormat/ELF.h" 21 #include "llvm/IR/Constants.h" 22 #include "llvm/IR/Function.h" 23 #include "llvm/IR/Metadata.h" 24 #include "llvm/IR/Module.h" 25 #include "llvm/MC/MCContext.h" 26 #include "llvm/MC/MCELFStreamer.h" 27 #include "llvm/MC/MCObjectFileInfo.h" 28 #include "llvm/MC/MCSectionELF.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 unsigned AMDGPUTargetStreamer::getMACH(StringRef GPU) const { 43 return llvm::StringSwitch<unsigned>(GPU) 44 // Radeon HD 2000/3000 Series (R600). 45 .Case("r600", ELF::EF_AMDGPU_MACH_R600_R600) 46 .Case("r630", ELF::EF_AMDGPU_MACH_R600_R630) 47 .Case("rs880", ELF::EF_AMDGPU_MACH_R600_RS880) 48 .Case("rv670", ELF::EF_AMDGPU_MACH_R600_RV670) 49 // Radeon HD 4000 Series (R700). 50 .Case("rv710", ELF::EF_AMDGPU_MACH_R600_RV710) 51 .Case("rv730", ELF::EF_AMDGPU_MACH_R600_RV730) 52 .Case("rv770", ELF::EF_AMDGPU_MACH_R600_RV770) 53 // Radeon HD 5000 Series (Evergreen). 54 .Case("cedar", ELF::EF_AMDGPU_MACH_R600_CEDAR) 55 .Case("cypress", ELF::EF_AMDGPU_MACH_R600_CYPRESS) 56 .Case("juniper", ELF::EF_AMDGPU_MACH_R600_JUNIPER) 57 .Case("redwood", ELF::EF_AMDGPU_MACH_R600_REDWOOD) 58 .Case("sumo", ELF::EF_AMDGPU_MACH_R600_SUMO) 59 // Radeon HD 6000 Series (Northern Islands). 60 .Case("barts", ELF::EF_AMDGPU_MACH_R600_BARTS) 61 .Case("caicos", ELF::EF_AMDGPU_MACH_R600_CAICOS) 62 .Case("cayman", ELF::EF_AMDGPU_MACH_R600_CAYMAN) 63 .Case("turks", ELF::EF_AMDGPU_MACH_R600_TURKS) 64 // AMDGCN GFX6. 65 .Case("gfx600", ELF::EF_AMDGPU_MACH_AMDGCN_GFX600) 66 .Case("tahiti", ELF::EF_AMDGPU_MACH_AMDGCN_GFX600) 67 .Case("gfx601", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601) 68 .Case("hainan", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601) 69 .Case("oland", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601) 70 .Case("pitcairn", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601) 71 .Case("verde", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601) 72 // AMDGCN GFX7. 73 .Case("gfx700", ELF::EF_AMDGPU_MACH_AMDGCN_GFX700) 74 .Case("kaveri", ELF::EF_AMDGPU_MACH_AMDGCN_GFX700) 75 .Case("gfx701", ELF::EF_AMDGPU_MACH_AMDGCN_GFX701) 76 .Case("hawaii", ELF::EF_AMDGPU_MACH_AMDGCN_GFX701) 77 .Case("gfx702", ELF::EF_AMDGPU_MACH_AMDGCN_GFX702) 78 .Case("gfx703", ELF::EF_AMDGPU_MACH_AMDGCN_GFX703) 79 .Case("kabini", ELF::EF_AMDGPU_MACH_AMDGCN_GFX703) 80 .Case("mullins", ELF::EF_AMDGPU_MACH_AMDGCN_GFX703) 81 .Case("gfx704", ELF::EF_AMDGPU_MACH_AMDGCN_GFX704) 82 .Case("bonaire", ELF::EF_AMDGPU_MACH_AMDGCN_GFX704) 83 // AMDGCN GFX8. 84 .Case("gfx801", ELF::EF_AMDGPU_MACH_AMDGCN_GFX801) 85 .Case("carrizo", ELF::EF_AMDGPU_MACH_AMDGCN_GFX801) 86 .Case("gfx802", ELF::EF_AMDGPU_MACH_AMDGCN_GFX802) 87 .Case("iceland", ELF::EF_AMDGPU_MACH_AMDGCN_GFX802) 88 .Case("tonga", ELF::EF_AMDGPU_MACH_AMDGCN_GFX802) 89 .Case("gfx803", ELF::EF_AMDGPU_MACH_AMDGCN_GFX803) 90 .Case("fiji", ELF::EF_AMDGPU_MACH_AMDGCN_GFX803) 91 .Case("polaris10", ELF::EF_AMDGPU_MACH_AMDGCN_GFX803) 92 .Case("polaris11", ELF::EF_AMDGPU_MACH_AMDGCN_GFX803) 93 .Case("gfx810", ELF::EF_AMDGPU_MACH_AMDGCN_GFX810) 94 .Case("stoney", ELF::EF_AMDGPU_MACH_AMDGCN_GFX810) 95 // AMDGCN GFX9. 96 .Case("gfx900", ELF::EF_AMDGPU_MACH_AMDGCN_GFX900) 97 .Case("gfx902", ELF::EF_AMDGPU_MACH_AMDGCN_GFX902) 98 // Not specified processor. 99 .Default(ELF::EF_AMDGPU_MACH_NONE); 100 } 101 102 bool AMDGPUTargetStreamer::EmitHSAMetadata(StringRef HSAMetadataString) { 103 HSAMD::Metadata HSAMetadata; 104 if (HSAMD::fromString(HSAMetadataString, HSAMetadata)) 105 return false; 106 107 return EmitHSAMetadata(HSAMetadata); 108 } 109 110 //===----------------------------------------------------------------------===// 111 // AMDGPUTargetAsmStreamer 112 //===----------------------------------------------------------------------===// 113 114 AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S, 115 formatted_raw_ostream &OS) 116 : AMDGPUTargetStreamer(S), OS(OS) { } 117 118 void 119 AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major, 120 uint32_t Minor) { 121 OS << "\t.hsa_code_object_version " << 122 Twine(Major) << "," << Twine(Minor) << '\n'; 123 } 124 125 void 126 AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major, 127 uint32_t Minor, 128 uint32_t Stepping, 129 StringRef VendorName, 130 StringRef ArchName) { 131 OS << "\t.hsa_code_object_isa " << 132 Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) << 133 ",\"" << VendorName << "\",\"" << ArchName << "\"\n"; 134 135 } 136 137 void 138 AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) { 139 OS << "\t.amd_kernel_code_t\n"; 140 dumpAmdKernelCode(&Header, OS, "\t\t"); 141 OS << "\t.end_amd_kernel_code_t\n"; 142 } 143 144 void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName, 145 unsigned Type) { 146 switch (Type) { 147 default: llvm_unreachable("Invalid AMDGPU symbol type"); 148 case ELF::STT_AMDGPU_HSA_KERNEL: 149 OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ; 150 break; 151 } 152 } 153 154 bool AMDGPUTargetAsmStreamer::EmitISAVersion(StringRef IsaVersionString) { 155 OS << "\t.amd_amdgpu_isa \"" << IsaVersionString << "\"\n"; 156 return true; 157 } 158 159 bool AMDGPUTargetAsmStreamer::EmitHSAMetadata( 160 const AMDGPU::HSAMD::Metadata &HSAMetadata) { 161 std::string HSAMetadataString; 162 if (HSAMD::toString(HSAMetadata, HSAMetadataString)) 163 return false; 164 165 OS << '\t' << HSAMD::AssemblerDirectiveBegin << '\n'; 166 OS << HSAMetadataString << '\n'; 167 OS << '\t' << HSAMD::AssemblerDirectiveEnd << '\n'; 168 return true; 169 } 170 171 bool AMDGPUTargetAsmStreamer::EmitPALMetadata( 172 const PALMD::Metadata &PALMetadata) { 173 std::string PALMetadataString; 174 if (PALMD::toString(PALMetadata, PALMetadataString)) 175 return false; 176 177 OS << '\t' << PALMD::AssemblerDirective << PALMetadataString << '\n'; 178 return true; 179 } 180 181 //===----------------------------------------------------------------------===// 182 // AMDGPUTargetELFStreamer 183 //===----------------------------------------------------------------------===// 184 185 AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer( 186 MCStreamer &S, const MCSubtargetInfo &STI) 187 : AMDGPUTargetStreamer(S), Streamer(S) { 188 MCAssembler &MCA = getStreamer().getAssembler(); 189 unsigned EFlags = MCA.getELFHeaderEFlags(); 190 191 EFlags &= ~ELF::EF_AMDGPU_MACH; 192 EFlags |= getMACH(STI.getCPU()); 193 194 EFlags &= ~ELF::EF_AMDGPU_XNACK; 195 if (AMDGPU::hasXNACK(STI)) 196 EFlags |= ELF::EF_AMDGPU_XNACK; 197 198 MCA.setELFHeaderEFlags(EFlags); 199 } 200 201 MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() { 202 return static_cast<MCELFStreamer &>(Streamer); 203 } 204 205 void AMDGPUTargetELFStreamer::EmitAMDGPUNote( 206 const MCExpr *DescSZ, unsigned NoteType, 207 function_ref<void(MCELFStreamer &)> EmitDesc) { 208 auto &S = getStreamer(); 209 auto &Context = S.getContext(); 210 211 auto NameSZ = sizeof(ElfNote::NoteName); 212 213 S.PushSection(); 214 S.SwitchSection(Context.getELFSection( 215 ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC)); 216 S.EmitIntValue(NameSZ, 4); // namesz 217 S.EmitValue(DescSZ, 4); // descz 218 S.EmitIntValue(NoteType, 4); // type 219 S.EmitBytes(StringRef(ElfNote::NoteName, NameSZ)); // name 220 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0 221 EmitDesc(S); // desc 222 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0 223 S.PopSection(); 224 } 225 226 void 227 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major, 228 uint32_t Minor) { 229 230 EmitAMDGPUNote( 231 MCConstantExpr::create(8, getContext()), 232 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION, 233 [&](MCELFStreamer &OS){ 234 OS.EmitIntValue(Major, 4); 235 OS.EmitIntValue(Minor, 4); 236 } 237 ); 238 } 239 240 void 241 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major, 242 uint32_t Minor, 243 uint32_t Stepping, 244 StringRef VendorName, 245 StringRef ArchName) { 246 uint16_t VendorNameSize = VendorName.size() + 1; 247 uint16_t ArchNameSize = ArchName.size() + 1; 248 249 unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) + 250 sizeof(Major) + sizeof(Minor) + sizeof(Stepping) + 251 VendorNameSize + ArchNameSize; 252 253 EmitAMDGPUNote( 254 MCConstantExpr::create(DescSZ, getContext()), 255 ElfNote::NT_AMDGPU_HSA_ISA, 256 [&](MCELFStreamer &OS) { 257 OS.EmitIntValue(VendorNameSize, 2); 258 OS.EmitIntValue(ArchNameSize, 2); 259 OS.EmitIntValue(Major, 4); 260 OS.EmitIntValue(Minor, 4); 261 OS.EmitIntValue(Stepping, 4); 262 OS.EmitBytes(VendorName); 263 OS.EmitIntValue(0, 1); // NULL terminate VendorName 264 OS.EmitBytes(ArchName); 265 OS.EmitIntValue(0, 1); // NULL terminte ArchName 266 } 267 ); 268 } 269 270 void 271 AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) { 272 273 MCStreamer &OS = getStreamer(); 274 OS.PushSection(); 275 OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header))); 276 OS.PopSection(); 277 } 278 279 void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName, 280 unsigned Type) { 281 MCSymbolELF *Symbol = cast<MCSymbolELF>( 282 getStreamer().getContext().getOrCreateSymbol(SymbolName)); 283 Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL); 284 } 285 286 bool AMDGPUTargetELFStreamer::EmitISAVersion(StringRef IsaVersionString) { 287 // Create two labels to mark the beginning and end of the desc field 288 // and a MCExpr to calculate the size of the desc field. 289 auto &Context = getContext(); 290 auto *DescBegin = Context.createTempSymbol(); 291 auto *DescEnd = Context.createTempSymbol(); 292 auto *DescSZ = MCBinaryExpr::createSub( 293 MCSymbolRefExpr::create(DescEnd, Context), 294 MCSymbolRefExpr::create(DescBegin, Context), Context); 295 296 EmitAMDGPUNote( 297 DescSZ, 298 ELF::NT_AMD_AMDGPU_ISA, 299 [&](MCELFStreamer &OS) { 300 OS.EmitLabel(DescBegin); 301 OS.EmitBytes(IsaVersionString); 302 OS.EmitLabel(DescEnd); 303 } 304 ); 305 return true; 306 } 307 308 bool AMDGPUTargetELFStreamer::EmitHSAMetadata( 309 const AMDGPU::HSAMD::Metadata &HSAMetadata) { 310 std::string HSAMetadataString; 311 if (HSAMD::toString(HSAMetadata, HSAMetadataString)) 312 return false; 313 314 // Create two labels to mark the beginning and end of the desc field 315 // and a MCExpr to calculate the size of the desc field. 316 auto &Context = getContext(); 317 auto *DescBegin = Context.createTempSymbol(); 318 auto *DescEnd = Context.createTempSymbol(); 319 auto *DescSZ = MCBinaryExpr::createSub( 320 MCSymbolRefExpr::create(DescEnd, Context), 321 MCSymbolRefExpr::create(DescBegin, Context), Context); 322 323 EmitAMDGPUNote( 324 DescSZ, 325 ELF::NT_AMD_AMDGPU_HSA_METADATA, 326 [&](MCELFStreamer &OS) { 327 OS.EmitLabel(DescBegin); 328 OS.EmitBytes(HSAMetadataString); 329 OS.EmitLabel(DescEnd); 330 } 331 ); 332 return true; 333 } 334 335 bool AMDGPUTargetELFStreamer::EmitPALMetadata( 336 const PALMD::Metadata &PALMetadata) { 337 EmitAMDGPUNote( 338 MCConstantExpr::create(PALMetadata.size() * sizeof(uint32_t), getContext()), 339 ELF::NT_AMD_AMDGPU_PAL_METADATA, 340 [&](MCELFStreamer &OS){ 341 for (auto I : PALMetadata) 342 OS.EmitIntValue(I, sizeof(uint32_t)); 343 } 344 ); 345 return true; 346 } 347