]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
MFV r322236: 8126 ztest assertion failed in dbuf_dirty due to dn_nlevels changing
[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 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 bool AMDGPUTargetAsmStreamer::EmitCodeObjectMetadata(StringRef YamlString) {
104   auto VerifiedYamlString = CodeObjectMetadataStreamer.toYamlString(YamlString);
105   if (!VerifiedYamlString)
106     return false;
107
108   OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveBegin << '\n';
109   OS << VerifiedYamlString.get();
110   OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveEnd << '\n';
111
112   return true;
113 }
114
115 //===----------------------------------------------------------------------===//
116 // AMDGPUTargetELFStreamer
117 //===----------------------------------------------------------------------===//
118
119 AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
120     : AMDGPUTargetStreamer(S), Streamer(S) {}
121
122 MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
123   return static_cast<MCELFStreamer &>(Streamer);
124 }
125
126 void AMDGPUTargetELFStreamer::EmitAMDGPUNote(
127     const MCExpr *DescSZ, ElfNote::NoteType Type,
128     function_ref<void(MCELFStreamer &)> EmitDesc) {
129   auto &S = getStreamer();
130   auto &Context = S.getContext();
131
132   auto NameSZ = sizeof(ElfNote::NoteName);
133
134   S.PushSection();
135   S.SwitchSection(Context.getELFSection(
136     ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
137   S.EmitIntValue(NameSZ, 4);                                  // namesz
138   S.EmitValue(DescSZ, 4);                                     // descz
139   S.EmitIntValue(Type, 4);                                    // type
140   S.EmitBytes(StringRef(ElfNote::NoteName, NameSZ));          // name
141   S.EmitValueToAlignment(4, 0, 1, 0);                         // padding 0
142   EmitDesc(S);                                                // desc
143   S.EmitValueToAlignment(4, 0, 1, 0);                         // padding 0
144   S.PopSection();
145 }
146
147 void
148 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
149                                                            uint32_t Minor) {
150
151   EmitAMDGPUNote(
152     MCConstantExpr::create(8, getContext()),
153     ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION,
154     [&](MCELFStreamer &OS){
155       OS.EmitIntValue(Major, 4);
156       OS.EmitIntValue(Minor, 4);
157     }
158   );
159 }
160
161 void
162 AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
163                                                        uint32_t Minor,
164                                                        uint32_t Stepping,
165                                                        StringRef VendorName,
166                                                        StringRef ArchName) {
167   uint16_t VendorNameSize = VendorName.size() + 1;
168   uint16_t ArchNameSize = ArchName.size() + 1;
169
170   unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
171     sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
172     VendorNameSize + ArchNameSize;
173
174   EmitAMDGPUNote(
175     MCConstantExpr::create(DescSZ, getContext()),
176     ElfNote::NT_AMDGPU_HSA_ISA,
177     [&](MCELFStreamer &OS) {
178       OS.EmitIntValue(VendorNameSize, 2);
179       OS.EmitIntValue(ArchNameSize, 2);
180       OS.EmitIntValue(Major, 4);
181       OS.EmitIntValue(Minor, 4);
182       OS.EmitIntValue(Stepping, 4);
183       OS.EmitBytes(VendorName);
184       OS.EmitIntValue(0, 1); // NULL terminate VendorName
185       OS.EmitBytes(ArchName);
186       OS.EmitIntValue(0, 1); // NULL terminte ArchName
187     }
188   );
189 }
190
191 void
192 AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
193
194   MCStreamer &OS = getStreamer();
195   OS.PushSection();
196   OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
197   OS.PopSection();
198 }
199
200 void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
201                                                    unsigned Type) {
202   MCSymbolELF *Symbol = cast<MCSymbolELF>(
203       getStreamer().getContext().getOrCreateSymbol(SymbolName));
204   Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
205 }
206
207 bool AMDGPUTargetELFStreamer::EmitCodeObjectMetadata(StringRef YamlString) {
208   auto VerifiedYamlString = CodeObjectMetadataStreamer.toYamlString(YamlString);
209   if (!VerifiedYamlString)
210     return false;
211
212   // Create two labels to mark the beginning and end of the desc field
213   // and a MCExpr to calculate the size of the desc field.
214   auto &Context = getContext();
215   auto *DescBegin = Context.createTempSymbol();
216   auto *DescEnd = Context.createTempSymbol();
217   auto *DescSZ = MCBinaryExpr::createSub(
218     MCSymbolRefExpr::create(DescEnd, Context),
219     MCSymbolRefExpr::create(DescBegin, Context), Context);
220
221   EmitAMDGPUNote(
222     DescSZ,
223     ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_METADATA,
224     [&](MCELFStreamer &OS) {
225       OS.EmitLabel(DescBegin);
226       OS.EmitBytes(VerifiedYamlString.get());
227       OS.EmitLabel(DescEnd);
228     }
229   );
230
231   return true;
232 }