blob: 4d4fdf6ed85aa82f51e4f9e74a1c1a6df6274f9d [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
Tom Stellard347ac792015-06-26 21:15:07 +000042AMDGPUTargetStreamer::AMDGPUTargetStreamer(MCStreamer &S)
Yaxun Liud6fbe652016-11-10 21:18:49 +000043 : MCTargetStreamer(S) {}
Tom Stellard347ac792015-06-26 21:15:07 +000044
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000045bool AMDGPUTargetStreamer::EmitHSAMetadata(StringRef HSAMetadataString) {
46 HSAMD::Metadata HSAMetadata;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +000047 if (HSAMD::fromString(HSAMetadataString, HSAMetadata))
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000048 return false;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000049
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000050 return EmitHSAMetadata(HSAMetadata);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000051}
52
Tom Stellard347ac792015-06-26 21:15:07 +000053//===----------------------------------------------------------------------===//
54// AMDGPUTargetAsmStreamer
55//===----------------------------------------------------------------------===//
56
57AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
58 formatted_raw_ostream &OS)
59 : AMDGPUTargetStreamer(S), OS(OS) { }
60
61void
62AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
63 uint32_t Minor) {
64 OS << "\t.hsa_code_object_version " <<
65 Twine(Major) << "," << Twine(Minor) << '\n';
66}
67
68void
69AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
70 uint32_t Minor,
71 uint32_t Stepping,
72 StringRef VendorName,
73 StringRef ArchName) {
74 OS << "\t.hsa_code_object_isa " <<
75 Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) <<
76 ",\"" << VendorName << "\",\"" << ArchName << "\"\n";
77
78}
79
Tom Stellardff7416b2015-06-26 21:58:31 +000080void
81AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
Sam Koltona2e5c882016-09-09 10:08:02 +000082 OS << "\t.amd_kernel_code_t\n";
83 dumpAmdKernelCode(&Header, OS, "\t\t");
84 OS << "\t.end_amd_kernel_code_t\n";
Tom Stellardff7416b2015-06-26 21:58:31 +000085}
86
Tom Stellard1e1b05d2015-11-06 11:45:14 +000087void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
88 unsigned Type) {
89 switch (Type) {
90 default: llvm_unreachable("Invalid AMDGPU symbol type");
91 case ELF::STT_AMDGPU_HSA_KERNEL:
92 OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ;
93 break;
94 }
95}
96
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000097bool AMDGPUTargetAsmStreamer::EmitHSAMetadata(
98 const AMDGPU::HSAMD::Metadata &HSAMetadata) {
99 std::string HSAMetadataString;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +0000100 if (HSAMD::toString(HSAMetadata, HSAMetadataString))
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000101 return false;
Sam Kolton69c8aa22016-12-19 11:43:15 +0000102
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000103 OS << '\t' << HSAMD::AssemblerDirectiveBegin << '\n';
104 OS << HSAMetadataString << '\n';
105 OS << '\t' << HSAMD::AssemblerDirectiveEnd << '\n';
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000106 return true;
Sam Kolton69c8aa22016-12-19 11:43:15 +0000107}
108
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000109bool AMDGPUTargetAsmStreamer::EmitPALMetadata(
110 const PALMD::Metadata &PALMetadata) {
111 std::string PALMetadataString;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +0000112 if (PALMD::toString(PALMetadata, PALMetadataString))
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000113 return false;
114
115 OS << '\t' << PALMD::AssemblerDirective << PALMetadataString << '\n';
Tim Renouf72800f02017-10-03 19:03:52 +0000116 return true;
117}
118
Tom Stellard347ac792015-06-26 21:15:07 +0000119//===----------------------------------------------------------------------===//
120// AMDGPUTargetELFStreamer
121//===----------------------------------------------------------------------===//
122
123AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
Yaxun Liud6fbe652016-11-10 21:18:49 +0000124 : AMDGPUTargetStreamer(S), Streamer(S) {}
Tom Stellard347ac792015-06-26 21:15:07 +0000125
126MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
127 return static_cast<MCELFStreamer &>(Streamer);
128}
129
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000130void AMDGPUTargetELFStreamer::EmitAMDGPUNote(
Konstantin Zhuravlyov70303c02017-10-12 18:59:54 +0000131 const MCExpr *DescSZ, unsigned NoteType,
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000132 function_ref<void(MCELFStreamer &)> EmitDesc) {
Sam Kolton69c8aa22016-12-19 11:43:15 +0000133 auto &S = getStreamer();
134 auto &Context = S.getContext();
Tom Stellard347ac792015-06-26 21:15:07 +0000135
Yaxun Liu874d26a2017-03-10 19:35:43 +0000136 auto NameSZ = sizeof(ElfNote::NoteName);
Sam Kolton69c8aa22016-12-19 11:43:15 +0000137
138 S.PushSection();
139 S.SwitchSection(Context.getELFSection(
Yaxun Liu874d26a2017-03-10 19:35:43 +0000140 ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
Sam Kolton69c8aa22016-12-19 11:43:15 +0000141 S.EmitIntValue(NameSZ, 4); // namesz
142 S.EmitValue(DescSZ, 4); // descz
Konstantin Zhuravlyov70303c02017-10-12 18:59:54 +0000143 S.EmitIntValue(NoteType, 4); // type
Yaxun Liu874d26a2017-03-10 19:35:43 +0000144 S.EmitBytes(StringRef(ElfNote::NoteName, NameSZ)); // name
Sam Kolton69c8aa22016-12-19 11:43:15 +0000145 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
146 EmitDesc(S); // desc
147 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
148 S.PopSection();
149}
150
151void
152AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
153 uint32_t Minor) {
154
155 EmitAMDGPUNote(
156 MCConstantExpr::create(8, getContext()),
Yaxun Liu874d26a2017-03-10 19:35:43 +0000157 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000158 [&](MCELFStreamer &OS){
159 OS.EmitIntValue(Major, 4);
160 OS.EmitIntValue(Minor, 4);
161 }
162 );
Tom Stellard347ac792015-06-26 21:15:07 +0000163}
164
165void
166AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
167 uint32_t Minor,
168 uint32_t Stepping,
169 StringRef VendorName,
170 StringRef ArchName) {
Tom Stellard347ac792015-06-26 21:15:07 +0000171 uint16_t VendorNameSize = VendorName.size() + 1;
172 uint16_t ArchNameSize = ArchName.size() + 1;
Matt Arsenaultb4493e92017-02-10 02:42:31 +0000173
Tom Stellard347ac792015-06-26 21:15:07 +0000174 unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
Sam Kolton69c8aa22016-12-19 11:43:15 +0000175 sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
176 VendorNameSize + ArchNameSize;
Tom Stellard347ac792015-06-26 21:15:07 +0000177
Sam Kolton69c8aa22016-12-19 11:43:15 +0000178 EmitAMDGPUNote(
179 MCConstantExpr::create(DescSZ, getContext()),
Yaxun Liu874d26a2017-03-10 19:35:43 +0000180 ElfNote::NT_AMDGPU_HSA_ISA,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000181 [&](MCELFStreamer &OS) {
182 OS.EmitIntValue(VendorNameSize, 2);
183 OS.EmitIntValue(ArchNameSize, 2);
184 OS.EmitIntValue(Major, 4);
185 OS.EmitIntValue(Minor, 4);
186 OS.EmitIntValue(Stepping, 4);
187 OS.EmitBytes(VendorName);
188 OS.EmitIntValue(0, 1); // NULL terminate VendorName
189 OS.EmitBytes(ArchName);
190 OS.EmitIntValue(0, 1); // NULL terminte ArchName
191 }
192 );
Tom Stellard347ac792015-06-26 21:15:07 +0000193}
Tom Stellardff7416b2015-06-26 21:58:31 +0000194
195void
196AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
197
198 MCStreamer &OS = getStreamer();
199 OS.PushSection();
Tom Stellardff7416b2015-06-26 21:58:31 +0000200 OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
201 OS.PopSection();
202}
Tom Stellard1e1b05d2015-11-06 11:45:14 +0000203
204void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
205 unsigned Type) {
206 MCSymbolELF *Symbol = cast<MCSymbolELF>(
207 getStreamer().getContext().getOrCreateSymbol(SymbolName));
208 Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
209}
Tom Stellard00f2f912015-12-02 19:47:57 +0000210
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000211bool AMDGPUTargetELFStreamer::EmitHSAMetadata(
212 const AMDGPU::HSAMD::Metadata &HSAMetadata) {
213 std::string HSAMetadataString;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +0000214 if (HSAMD::toString(HSAMetadata, HSAMetadataString))
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000215 return false;
Konstantin Zhuravlyov972948b2017-02-27 07:55:17 +0000216
Yaxun Liud6fbe652016-11-10 21:18:49 +0000217 // Create two labels to mark the beginning and end of the desc field
218 // and a MCExpr to calculate the size of the desc field.
Sam Kolton69c8aa22016-12-19 11:43:15 +0000219 auto &Context = getContext();
Yaxun Liud6fbe652016-11-10 21:18:49 +0000220 auto *DescBegin = Context.createTempSymbol();
221 auto *DescEnd = Context.createTempSymbol();
222 auto *DescSZ = MCBinaryExpr::createSub(
Sam Kolton69c8aa22016-12-19 11:43:15 +0000223 MCSymbolRefExpr::create(DescEnd, Context),
224 MCSymbolRefExpr::create(DescBegin, Context), Context);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000225
Sam Kolton69c8aa22016-12-19 11:43:15 +0000226 EmitAMDGPUNote(
227 DescSZ,
Konstantin Zhuravlyov70303c02017-10-12 18:59:54 +0000228 ELF::NT_AMD_AMDGPU_HSA_METADATA,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000229 [&](MCELFStreamer &OS) {
230 OS.EmitLabel(DescBegin);
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000231 OS.EmitBytes(HSAMetadataString);
Sam Kolton69c8aa22016-12-19 11:43:15 +0000232 OS.EmitLabel(DescEnd);
233 }
234 );
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000235 return true;
Yaxun Liud6fbe652016-11-10 21:18:49 +0000236}
Tim Renouf72800f02017-10-03 19:03:52 +0000237
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000238bool AMDGPUTargetELFStreamer::EmitPALMetadata(
239 const PALMD::Metadata &PALMetadata) {
Tim Renouf72800f02017-10-03 19:03:52 +0000240 EmitAMDGPUNote(
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000241 MCConstantExpr::create(PALMetadata.size() * sizeof(uint32_t), getContext()),
Konstantin Zhuravlyov70303c02017-10-12 18:59:54 +0000242 ELF::NT_AMD_AMDGPU_PAL_METADATA,
Tim Renouf72800f02017-10-03 19:03:52 +0000243 [&](MCELFStreamer &OS){
Konstantin Zhuravlyovc3beb6a2017-10-11 22:41:09 +0000244 for (auto I : PALMetadata)
Tim Renouf72800f02017-10-03 19:03:52 +0000245 OS.EmitIntValue(I, sizeof(uint32_t));
246 }
247 );
248 return true;
249}