blob: d897956daccf49ce358869f0d80c3468c0a59276 [file] [log] [blame]
Tom Stellard347ac792015-06-26 21:15:07 +00001//===-- 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"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000015#include "AMDGPU.h"
Tom Stellardff7416b2015-06-26 21:58:31 +000016#include "SIDefines.h"
Tom Stellarde135ffd2015-09-25 21:41:28 +000017#include "Utils/AMDGPUBaseInfo.h"
Sam Koltona2e5c882016-09-09 10:08:02 +000018#include "Utils/AMDKernelCodeTUtils.h"
Tom Stellard347ac792015-06-26 21:15:07 +000019#include "llvm/ADT/Twine.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000020#include "llvm/BinaryFormat/ELF.h"
Yaxun Liud6fbe652016-11-10 21:18:49 +000021#include "llvm/IR/Constants.h"
22#include "llvm/IR/Function.h"
23#include "llvm/IR/Metadata.h"
24#include "llvm/IR/Module.h"
Tom Stellard347ac792015-06-26 21:15:07 +000025#include "llvm/MC/MCContext.h"
26#include "llvm/MC/MCELFStreamer.h"
Tom Stellardff7416b2015-06-26 21:58:31 +000027#include "llvm/MC/MCObjectFileInfo.h"
Tom Stellard347ac792015-06-26 21:15:07 +000028#include "llvm/MC/MCSectionELF.h"
Tom Stellard347ac792015-06-26 21:15:07 +000029#include "llvm/Support/FormattedStream.h"
30
Yaxun Liud6fbe652016-11-10 21:18:49 +000031namespace llvm {
32#include "AMDGPUPTNote.h"
33}
34
Tom Stellard347ac792015-06-26 21:15:07 +000035using namespace llvm;
Yaxun Liud6fbe652016-11-10 21:18:49 +000036using namespace llvm::AMDGPU;
Tom Stellard347ac792015-06-26 21:15:07 +000037
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000038//===----------------------------------------------------------------------===//
39// AMDGPUTargetStreamer
40//===----------------------------------------------------------------------===//
41
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000042bool AMDGPUTargetStreamer::EmitHSAMetadata(StringRef HSAMetadataString) {
43 HSAMD::Metadata HSAMetadata;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +000044 if (HSAMD::fromString(HSAMetadataString, HSAMetadata))
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000045 return false;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000046
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000047 return EmitHSAMetadata(HSAMetadata);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000048}
49
Tom Stellard347ac792015-06-26 21:15:07 +000050//===----------------------------------------------------------------------===//
51// AMDGPUTargetAsmStreamer
52//===----------------------------------------------------------------------===//
53
54AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
55 formatted_raw_ostream &OS)
56 : AMDGPUTargetStreamer(S), OS(OS) { }
57
58void
59AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
60 uint32_t Minor) {
61 OS << "\t.hsa_code_object_version " <<
62 Twine(Major) << "," << Twine(Minor) << '\n';
63}
64
65void
66AMDGPUTargetAsmStreamer::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
Tom Stellardff7416b2015-06-26 21:58:31 +000077void
78AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
Sam Koltona2e5c882016-09-09 10:08:02 +000079 OS << "\t.amd_kernel_code_t\n";
80 dumpAmdKernelCode(&Header, OS, "\t\t");
81 OS << "\t.end_amd_kernel_code_t\n";
Tom Stellardff7416b2015-06-26 21:58:31 +000082}
83
Tom Stellard1e1b05d2015-11-06 11:45:14 +000084void 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
Konstantin Zhuravlyov9c05b2b2017-10-14 15:40:33 +000094bool AMDGPUTargetAsmStreamer::EmitISAVersion(StringRef IsaVersionString) {
95 OS << "\t.amd_amdgpu_isa \"" << IsaVersionString << "\"\n";
96 return true;
97}
98
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000099bool AMDGPUTargetAsmStreamer::EmitHSAMetadata(
100 const AMDGPU::HSAMD::Metadata &HSAMetadata) {
101 std::string HSAMetadataString;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +0000102 if (HSAMD::toString(HSAMetadata, HSAMetadataString))
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000103 return false;
Sam Kolton69c8aa22016-12-19 11:43:15 +0000104
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000105 OS << '\t' << HSAMD::AssemblerDirectiveBegin << '\n';
106 OS << HSAMetadataString << '\n';
107 OS << '\t' << HSAMD::AssemblerDirectiveEnd << '\n';
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000108 return true;
Sam Kolton69c8aa22016-12-19 11:43:15 +0000109}
110
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000111bool AMDGPUTargetAsmStreamer::EmitPALMetadata(
112 const PALMD::Metadata &PALMetadata) {
113 std::string PALMetadataString;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +0000114 if (PALMD::toString(PALMetadata, PALMetadataString))
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000115 return false;
116
117 OS << '\t' << PALMD::AssemblerDirective << PALMetadataString << '\n';
Tim Renouf72800f02017-10-03 19:03:52 +0000118 return true;
119}
120
Tom Stellard347ac792015-06-26 21:15:07 +0000121//===----------------------------------------------------------------------===//
122// AMDGPUTargetELFStreamer
123//===----------------------------------------------------------------------===//
124
125AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
Yaxun Liud6fbe652016-11-10 21:18:49 +0000126 : AMDGPUTargetStreamer(S), Streamer(S) {}
Tom Stellard347ac792015-06-26 21:15:07 +0000127
128MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
129 return static_cast<MCELFStreamer &>(Streamer);
130}
131
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000132void AMDGPUTargetELFStreamer::EmitAMDGPUNote(
Konstantin Zhuravlyov70303c02017-10-12 18:59:54 +0000133 const MCExpr *DescSZ, unsigned NoteType,
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000134 function_ref<void(MCELFStreamer &)> EmitDesc) {
Sam Kolton69c8aa22016-12-19 11:43:15 +0000135 auto &S = getStreamer();
136 auto &Context = S.getContext();
Tom Stellard347ac792015-06-26 21:15:07 +0000137
Yaxun Liu874d26a2017-03-10 19:35:43 +0000138 auto NameSZ = sizeof(ElfNote::NoteName);
Sam Kolton69c8aa22016-12-19 11:43:15 +0000139
140 S.PushSection();
141 S.SwitchSection(Context.getELFSection(
Yaxun Liu874d26a2017-03-10 19:35:43 +0000142 ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
Sam Kolton69c8aa22016-12-19 11:43:15 +0000143 S.EmitIntValue(NameSZ, 4); // namesz
144 S.EmitValue(DescSZ, 4); // descz
Konstantin Zhuravlyov70303c02017-10-12 18:59:54 +0000145 S.EmitIntValue(NoteType, 4); // type
Yaxun Liu874d26a2017-03-10 19:35:43 +0000146 S.EmitBytes(StringRef(ElfNote::NoteName, NameSZ)); // name
Sam Kolton69c8aa22016-12-19 11:43:15 +0000147 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
153void
154AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
155 uint32_t Minor) {
156
157 EmitAMDGPUNote(
158 MCConstantExpr::create(8, getContext()),
Yaxun Liu874d26a2017-03-10 19:35:43 +0000159 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000160 [&](MCELFStreamer &OS){
161 OS.EmitIntValue(Major, 4);
162 OS.EmitIntValue(Minor, 4);
163 }
164 );
Tom Stellard347ac792015-06-26 21:15:07 +0000165}
166
167void
168AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
169 uint32_t Minor,
170 uint32_t Stepping,
171 StringRef VendorName,
172 StringRef ArchName) {
Tom Stellard347ac792015-06-26 21:15:07 +0000173 uint16_t VendorNameSize = VendorName.size() + 1;
174 uint16_t ArchNameSize = ArchName.size() + 1;
Matt Arsenaultb4493e92017-02-10 02:42:31 +0000175
Tom Stellard347ac792015-06-26 21:15:07 +0000176 unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
Sam Kolton69c8aa22016-12-19 11:43:15 +0000177 sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
178 VendorNameSize + ArchNameSize;
Tom Stellard347ac792015-06-26 21:15:07 +0000179
Sam Kolton69c8aa22016-12-19 11:43:15 +0000180 EmitAMDGPUNote(
181 MCConstantExpr::create(DescSZ, getContext()),
Yaxun Liu874d26a2017-03-10 19:35:43 +0000182 ElfNote::NT_AMDGPU_HSA_ISA,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000183 [&](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 );
Tom Stellard347ac792015-06-26 21:15:07 +0000195}
Tom Stellardff7416b2015-06-26 21:58:31 +0000196
197void
198AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
199
200 MCStreamer &OS = getStreamer();
201 OS.PushSection();
Tom Stellardff7416b2015-06-26 21:58:31 +0000202 OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
203 OS.PopSection();
204}
Tom Stellard1e1b05d2015-11-06 11:45:14 +0000205
206void 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}
Tom Stellard00f2f912015-12-02 19:47:57 +0000212
Konstantin Zhuravlyov9c05b2b2017-10-14 15:40:33 +0000213bool 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
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000235bool AMDGPUTargetELFStreamer::EmitHSAMetadata(
236 const AMDGPU::HSAMD::Metadata &HSAMetadata) {
237 std::string HSAMetadataString;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +0000238 if (HSAMD::toString(HSAMetadata, HSAMetadataString))
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000239 return false;
Konstantin Zhuravlyov972948b2017-02-27 07:55:17 +0000240
Yaxun Liud6fbe652016-11-10 21:18:49 +0000241 // 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.
Sam Kolton69c8aa22016-12-19 11:43:15 +0000243 auto &Context = getContext();
Yaxun Liud6fbe652016-11-10 21:18:49 +0000244 auto *DescBegin = Context.createTempSymbol();
245 auto *DescEnd = Context.createTempSymbol();
246 auto *DescSZ = MCBinaryExpr::createSub(
Sam Kolton69c8aa22016-12-19 11:43:15 +0000247 MCSymbolRefExpr::create(DescEnd, Context),
248 MCSymbolRefExpr::create(DescBegin, Context), Context);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000249
Sam Kolton69c8aa22016-12-19 11:43:15 +0000250 EmitAMDGPUNote(
251 DescSZ,
Konstantin Zhuravlyov70303c02017-10-12 18:59:54 +0000252 ELF::NT_AMD_AMDGPU_HSA_METADATA,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000253 [&](MCELFStreamer &OS) {
254 OS.EmitLabel(DescBegin);
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000255 OS.EmitBytes(HSAMetadataString);
Sam Kolton69c8aa22016-12-19 11:43:15 +0000256 OS.EmitLabel(DescEnd);
257 }
258 );
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000259 return true;
Yaxun Liud6fbe652016-11-10 21:18:49 +0000260}
Tim Renouf72800f02017-10-03 19:03:52 +0000261
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000262bool AMDGPUTargetELFStreamer::EmitPALMetadata(
263 const PALMD::Metadata &PALMetadata) {
Tim Renouf72800f02017-10-03 19:03:52 +0000264 EmitAMDGPUNote(
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000265 MCConstantExpr::create(PALMetadata.size() * sizeof(uint32_t), getContext()),
Konstantin Zhuravlyov70303c02017-10-12 18:59:54 +0000266 ELF::NT_AMD_AMDGPU_PAL_METADATA,
Tim Renouf72800f02017-10-03 19:03:52 +0000267 [&](MCELFStreamer &OS){
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000268 for (auto I : PALMetadata)
Tim Renouf72800f02017-10-03 19:03:52 +0000269 OS.EmitIntValue(I, sizeof(uint32_t));
270 }
271 );
272 return true;
273}