]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
Import tzdata 2018c
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AMDGPU / MCTargetDesc / AMDGPUTargetStreamer.cpp
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 bool AMDGPUTargetStreamer::EmitHSAMetadata(StringRef HSAMetadataString) {
43   HSAMD::Metadata HSAMetadata;
44   if (HSAMD::fromString(HSAMetadataString, HSAMetadata))
45     return false;
46
47   return EmitHSAMetadata(HSAMetadata);
48 }
49
50 //===----------------------------------------------------------------------===//
51 // AMDGPUTargetAsmStreamer
52 //===----------------------------------------------------------------------===//
53
54 AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
55                                                  formatted_raw_ostream &OS)
56     : AMDGPUTargetStreamer(S), OS(OS) { }
57
58 void
59 AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
60                                                            uint32_t Minor) {
61   OS << "\t.hsa_code_object_version " <<
62         Twine(Major) << "," << Twine(Minor) << '\n';
63 }
64
65 void
66 AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
67                                                        uint32_t Minor,
68                                                        uint32_t Stepping,
69                                                        StringRef VendorName,
70                                                        StringRef ArchName) {
71   OS << "\t.hsa_code_object_isa " <<
72         Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) <<
73         ",\"" << VendorName << "\",\"" << ArchName << "\"\n";
74
75 }
76
77 void
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";
82 }
83
84 void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
85                                                    unsigned Type) {
86   switch (Type) {
87     default: llvm_unreachable("Invalid AMDGPU symbol type");
88     case ELF::STT_AMDGPU_HSA_KERNEL:
89       OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ;
90       break;
91   }
92 }
93
94 bool AMDGPUTargetAsmStreamer::EmitISAVersion(StringRef IsaVersionString) {
95   OS << "\t.amd_amdgpu_isa \"" << IsaVersionString << "\"\n";
96   return true;
97 }
98
99 bool AMDGPUTargetAsmStreamer::EmitHSAMetadata(
100     const AMDGPU::HSAMD::Metadata &HSAMetadata) {
101   std::string HSAMetadataString;
102   if (HSAMD::toString(HSAMetadata, HSAMetadataString))
103     return false;
104
105   OS << '\t' << HSAMD::AssemblerDirectiveBegin << '\n';
106   OS << HSAMetadataString << '\n';
107   OS << '\t' << HSAMD::AssemblerDirectiveEnd << '\n';
108   return true;
109 }
110
111 bool AMDGPUTargetAsmStreamer::EmitPALMetadata(
112     const PALMD::Metadata &PALMetadata) {
113   std::string PALMetadataString;
114   if (PALMD::toString(PALMetadata, PALMetadataString))
115     return false;
116
117   OS << '\t' << PALMD::AssemblerDirective << PALMetadataString << '\n';
118   return true;
119 }
120
121 //===----------------------------------------------------------------------===//
122 // AMDGPUTargetELFStreamer
123 //===----------------------------------------------------------------------===//
124
125 AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
126     : AMDGPUTargetStreamer(S), Streamer(S) {}
127
128 MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
129   return static_cast<MCELFStreamer &>(Streamer);
130 }
131
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();
137
138   auto NameSZ = sizeof(ElfNote::NoteName);
139
140   S.PushSection();
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
148   EmitDesc(S);                                                // desc
149   S.EmitValueToAlignment(4, 0, 1, 0);                         // padding 0
150   S.PopSection();
151 }
152
153 void
154 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
155                                                            uint32_t Minor) {
156
157   EmitAMDGPUNote(
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);
163     }
164   );
165 }
166
167 void
168 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
169                                                        uint32_t Minor,
170                                                        uint32_t Stepping,
171                                                        StringRef VendorName,
172                                                        StringRef ArchName) {
173   uint16_t VendorNameSize = VendorName.size() + 1;
174   uint16_t ArchNameSize = ArchName.size() + 1;
175
176   unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
177     sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
178     VendorNameSize + ArchNameSize;
179
180   EmitAMDGPUNote(
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
193     }
194   );
195 }
196
197 void
198 AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
199
200   MCStreamer &OS = getStreamer();
201   OS.PushSection();
202   OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
203   OS.PopSection();
204 }
205
206 void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
207                                                    unsigned Type) {
208   MCSymbolELF *Symbol = cast<MCSymbolELF>(
209       getStreamer().getContext().getOrCreateSymbol(SymbolName));
210   Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
211 }
212
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);
222
223   EmitAMDGPUNote(
224     DescSZ,
225     ELF::NT_AMD_AMDGPU_ISA,
226     [&](MCELFStreamer &OS) {
227       OS.EmitLabel(DescBegin);
228       OS.EmitBytes(IsaVersionString);
229       OS.EmitLabel(DescEnd);
230     }
231   );
232   return true;
233 }
234
235 bool AMDGPUTargetELFStreamer::EmitHSAMetadata(
236     const AMDGPU::HSAMD::Metadata &HSAMetadata) {
237   std::string HSAMetadataString;
238   if (HSAMD::toString(HSAMetadata, HSAMetadataString))
239     return false;
240
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);
249
250   EmitAMDGPUNote(
251     DescSZ,
252     ELF::NT_AMD_AMDGPU_HSA_METADATA,
253     [&](MCELFStreamer &OS) {
254       OS.EmitLabel(DescBegin);
255       OS.EmitBytes(HSAMetadataString);
256       OS.EmitLabel(DescEnd);
257     }
258   );
259   return true;
260 }
261
262 bool AMDGPUTargetELFStreamer::EmitPALMetadata(
263     const PALMD::Metadata &PALMetadata) {
264   EmitAMDGPUNote(
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));
270     }
271   );
272   return true;
273 }