1 //===-- AMDGPUTargetStreamer.cpp - Mips Target Streamer Methods -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides AMDGPU specific target streamer methods.
12 //===----------------------------------------------------------------------===//
14 #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/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"
32 #include "AMDGPUPTNote.h"
36 using namespace llvm::AMDGPU;
38 //===----------------------------------------------------------------------===//
39 // AMDGPUTargetStreamer
40 //===----------------------------------------------------------------------===//
42 bool AMDGPUTargetStreamer::EmitHSAMetadata(StringRef HSAMetadataString) {
43 HSAMD::Metadata HSAMetadata;
44 if (HSAMD::fromString(HSAMetadataString, HSAMetadata))
47 return EmitHSAMetadata(HSAMetadata);
50 //===----------------------------------------------------------------------===//
51 // AMDGPUTargetAsmStreamer
52 //===----------------------------------------------------------------------===//
54 AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
55 formatted_raw_ostream &OS)
56 : AMDGPUTargetStreamer(S), OS(OS) { }
59 AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
61 OS << "\t.hsa_code_object_version " <<
62 Twine(Major) << "," << Twine(Minor) << '\n';
66 AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
71 OS << "\t.hsa_code_object_isa " <<
72 Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) <<
73 ",\"" << VendorName << "\",\"" << ArchName << "\"\n";
78 AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
79 OS << "\t.amd_kernel_code_t\n";
80 dumpAmdKernelCode(&Header, OS, "\t\t");
81 OS << "\t.end_amd_kernel_code_t\n";
84 void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
87 default: llvm_unreachable("Invalid AMDGPU symbol type");
88 case ELF::STT_AMDGPU_HSA_KERNEL:
89 OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ;
94 bool AMDGPUTargetAsmStreamer::EmitISAVersion(StringRef IsaVersionString) {
95 OS << "\t.amd_amdgpu_isa \"" << IsaVersionString << "\"\n";
99 bool AMDGPUTargetAsmStreamer::EmitHSAMetadata(
100 const AMDGPU::HSAMD::Metadata &HSAMetadata) {
101 std::string HSAMetadataString;
102 if (HSAMD::toString(HSAMetadata, HSAMetadataString))
105 OS << '\t' << HSAMD::AssemblerDirectiveBegin << '\n';
106 OS << HSAMetadataString << '\n';
107 OS << '\t' << HSAMD::AssemblerDirectiveEnd << '\n';
111 bool AMDGPUTargetAsmStreamer::EmitPALMetadata(
112 const PALMD::Metadata &PALMetadata) {
113 std::string PALMetadataString;
114 if (PALMD::toString(PALMetadata, PALMetadataString))
117 OS << '\t' << PALMD::AssemblerDirective << PALMetadataString << '\n';
121 //===----------------------------------------------------------------------===//
122 // AMDGPUTargetELFStreamer
123 //===----------------------------------------------------------------------===//
125 AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
126 : AMDGPUTargetStreamer(S), Streamer(S) {}
128 MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
129 return static_cast<MCELFStreamer &>(Streamer);
132 void AMDGPUTargetELFStreamer::EmitAMDGPUNote(
133 const MCExpr *DescSZ, unsigned NoteType,
134 function_ref<void(MCELFStreamer &)> EmitDesc) {
135 auto &S = getStreamer();
136 auto &Context = S.getContext();
138 auto NameSZ = sizeof(ElfNote::NoteName);
141 S.SwitchSection(Context.getELFSection(
142 ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
143 S.EmitIntValue(NameSZ, 4); // namesz
144 S.EmitValue(DescSZ, 4); // descz
145 S.EmitIntValue(NoteType, 4); // type
146 S.EmitBytes(StringRef(ElfNote::NoteName, NameSZ)); // name
147 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
149 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
154 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
158 MCConstantExpr::create(8, getContext()),
159 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION,
160 [&](MCELFStreamer &OS){
161 OS.EmitIntValue(Major, 4);
162 OS.EmitIntValue(Minor, 4);
168 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
171 StringRef VendorName,
172 StringRef ArchName) {
173 uint16_t VendorNameSize = VendorName.size() + 1;
174 uint16_t ArchNameSize = ArchName.size() + 1;
176 unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
177 sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
178 VendorNameSize + ArchNameSize;
181 MCConstantExpr::create(DescSZ, getContext()),
182 ElfNote::NT_AMDGPU_HSA_ISA,
183 [&](MCELFStreamer &OS) {
184 OS.EmitIntValue(VendorNameSize, 2);
185 OS.EmitIntValue(ArchNameSize, 2);
186 OS.EmitIntValue(Major, 4);
187 OS.EmitIntValue(Minor, 4);
188 OS.EmitIntValue(Stepping, 4);
189 OS.EmitBytes(VendorName);
190 OS.EmitIntValue(0, 1); // NULL terminate VendorName
191 OS.EmitBytes(ArchName);
192 OS.EmitIntValue(0, 1); // NULL terminte ArchName
198 AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
200 MCStreamer &OS = getStreamer();
202 OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
206 void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
208 MCSymbolELF *Symbol = cast<MCSymbolELF>(
209 getStreamer().getContext().getOrCreateSymbol(SymbolName));
210 Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
213 bool AMDGPUTargetELFStreamer::EmitISAVersion(StringRef IsaVersionString) {
214 // Create two labels to mark the beginning and end of the desc field
215 // and a MCExpr to calculate the size of the desc field.
216 auto &Context = getContext();
217 auto *DescBegin = Context.createTempSymbol();
218 auto *DescEnd = Context.createTempSymbol();
219 auto *DescSZ = MCBinaryExpr::createSub(
220 MCSymbolRefExpr::create(DescEnd, Context),
221 MCSymbolRefExpr::create(DescBegin, Context), Context);
225 ELF::NT_AMD_AMDGPU_ISA,
226 [&](MCELFStreamer &OS) {
227 OS.EmitLabel(DescBegin);
228 OS.EmitBytes(IsaVersionString);
229 OS.EmitLabel(DescEnd);
235 bool AMDGPUTargetELFStreamer::EmitHSAMetadata(
236 const AMDGPU::HSAMD::Metadata &HSAMetadata) {
237 std::string HSAMetadataString;
238 if (HSAMD::toString(HSAMetadata, HSAMetadataString))
241 // Create two labels to mark the beginning and end of the desc field
242 // and a MCExpr to calculate the size of the desc field.
243 auto &Context = getContext();
244 auto *DescBegin = Context.createTempSymbol();
245 auto *DescEnd = Context.createTempSymbol();
246 auto *DescSZ = MCBinaryExpr::createSub(
247 MCSymbolRefExpr::create(DescEnd, Context),
248 MCSymbolRefExpr::create(DescBegin, Context), Context);
252 ELF::NT_AMD_AMDGPU_HSA_METADATA,
253 [&](MCELFStreamer &OS) {
254 OS.EmitLabel(DescBegin);
255 OS.EmitBytes(HSAMetadataString);
256 OS.EmitLabel(DescEnd);
262 bool AMDGPUTargetELFStreamer::EmitPALMetadata(
263 const PALMD::Metadata &PALMetadata) {
265 MCConstantExpr::create(PALMetadata.size() * sizeof(uint32_t), getContext()),
266 ELF::NT_AMD_AMDGPU_PAL_METADATA,
267 [&](MCELFStreamer &OS){
268 for (auto I : PALMetadata)
269 OS.EmitIntValue(I, sizeof(uint32_t));