blob: 963171f44624625b7496d079ff6ff4653e939a2f [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
Yaxun Liud6fbe652016-11-10 21:18:49 +000014#include "AMDGPU.h"
Tom Stellard347ac792015-06-26 21:15:07 +000015#include "AMDGPUTargetStreamer.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"
Yaxun Liud6fbe652016-11-10 21:18:49 +000020#include "llvm/IR/Constants.h"
21#include "llvm/IR/Function.h"
22#include "llvm/IR/Metadata.h"
23#include "llvm/IR/Module.h"
Tom Stellard347ac792015-06-26 21:15:07 +000024#include "llvm/MC/MCContext.h"
25#include "llvm/MC/MCELFStreamer.h"
Tom Stellardff7416b2015-06-26 21:58:31 +000026#include "llvm/MC/MCObjectFileInfo.h"
Tom Stellard347ac792015-06-26 21:15:07 +000027#include "llvm/MC/MCSectionELF.h"
28#include "llvm/Support/ELF.h"
29#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 Zhuravlyov7498cd62017-03-22 22:32:22 +000045void AMDGPUTargetStreamer::EmitStartOfCodeObjectMetadata(
46 const FeatureBitset &Features, const Module &Mod) {
47 CodeObjectMetadataStreamer.begin(Features, Mod);
48}
49
50void AMDGPUTargetStreamer::EmitKernelCodeObjectMetadata(const Function &Func) {
51 CodeObjectMetadataStreamer.emitKernel(Func);
52}
53
54void AMDGPUTargetStreamer::EmitEndOfCodeObjectMetadata(
55 const FeatureBitset &Features) {
56 CodeObjectMetadataStreamer.end();
57 EmitCodeObjectMetadata(Features,
58 CodeObjectMetadataStreamer.toYamlString().get());
59}
60
Tom Stellard347ac792015-06-26 21:15:07 +000061//===----------------------------------------------------------------------===//
62// AMDGPUTargetAsmStreamer
63//===----------------------------------------------------------------------===//
64
65AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
66 formatted_raw_ostream &OS)
67 : AMDGPUTargetStreamer(S), OS(OS) { }
68
69void
70AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
71 uint32_t Minor) {
72 OS << "\t.hsa_code_object_version " <<
73 Twine(Major) << "," << Twine(Minor) << '\n';
74}
75
76void
77AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
78 uint32_t Minor,
79 uint32_t Stepping,
80 StringRef VendorName,
81 StringRef ArchName) {
82 OS << "\t.hsa_code_object_isa " <<
83 Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) <<
84 ",\"" << VendorName << "\",\"" << ArchName << "\"\n";
85
86}
87
Tom Stellardff7416b2015-06-26 21:58:31 +000088void
89AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
Sam Koltona2e5c882016-09-09 10:08:02 +000090 OS << "\t.amd_kernel_code_t\n";
91 dumpAmdKernelCode(&Header, OS, "\t\t");
92 OS << "\t.end_amd_kernel_code_t\n";
Tom Stellardff7416b2015-06-26 21:58:31 +000093}
94
Tom Stellard1e1b05d2015-11-06 11:45:14 +000095void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
96 unsigned Type) {
97 switch (Type) {
98 default: llvm_unreachable("Invalid AMDGPU symbol type");
99 case ELF::STT_AMDGPU_HSA_KERNEL:
100 OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ;
101 break;
102 }
103}
104
Tom Stellard00f2f912015-12-02 19:47:57 +0000105void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaModuleScopeGlobal(
106 StringRef GlobalName) {
107 OS << "\t.amdgpu_hsa_module_global " << GlobalName << '\n';
108}
109
110void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaProgramScopeGlobal(
111 StringRef GlobalName) {
112 OS << "\t.amdgpu_hsa_program_global " << GlobalName << '\n';
113}
114
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000115bool AMDGPUTargetAsmStreamer::EmitCodeObjectMetadata(
116 const FeatureBitset &Features, StringRef YamlString) {
117 auto VerifiedYamlString =
118 CodeObjectMetadataStreamer.toYamlString(Features, YamlString);
119 if (!VerifiedYamlString)
120 return false;
Sam Kolton69c8aa22016-12-19 11:43:15 +0000121
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000122 OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveBegin << '\n';
123 OS << VerifiedYamlString.get();
124 OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveEnd << '\n';
Konstantin Zhuravlyov972948b2017-02-27 07:55:17 +0000125
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000126 return true;
Sam Kolton69c8aa22016-12-19 11:43:15 +0000127}
128
Tom Stellard347ac792015-06-26 21:15:07 +0000129//===----------------------------------------------------------------------===//
130// AMDGPUTargetELFStreamer
131//===----------------------------------------------------------------------===//
132
133AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
Yaxun Liud6fbe652016-11-10 21:18:49 +0000134 : AMDGPUTargetStreamer(S), Streamer(S) {}
Tom Stellard347ac792015-06-26 21:15:07 +0000135
136MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
137 return static_cast<MCELFStreamer &>(Streamer);
138}
139
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000140void AMDGPUTargetELFStreamer::EmitAMDGPUNote(
Yaxun Liu874d26a2017-03-10 19:35:43 +0000141 const MCExpr *DescSZ, ElfNote::NoteType Type,
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000142 function_ref<void(MCELFStreamer &)> EmitDesc) {
Sam Kolton69c8aa22016-12-19 11:43:15 +0000143 auto &S = getStreamer();
144 auto &Context = S.getContext();
Tom Stellard347ac792015-06-26 21:15:07 +0000145
Yaxun Liu874d26a2017-03-10 19:35:43 +0000146 auto NameSZ = sizeof(ElfNote::NoteName);
Sam Kolton69c8aa22016-12-19 11:43:15 +0000147
148 S.PushSection();
149 S.SwitchSection(Context.getELFSection(
Yaxun Liu874d26a2017-03-10 19:35:43 +0000150 ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
Sam Kolton69c8aa22016-12-19 11:43:15 +0000151 S.EmitIntValue(NameSZ, 4); // namesz
152 S.EmitValue(DescSZ, 4); // descz
Yaxun Liu874d26a2017-03-10 19:35:43 +0000153 S.EmitIntValue(Type, 4); // type
154 S.EmitBytes(StringRef(ElfNote::NoteName, NameSZ)); // name
Sam Kolton69c8aa22016-12-19 11:43:15 +0000155 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
156 EmitDesc(S); // desc
157 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
158 S.PopSection();
159}
160
161void
162AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
163 uint32_t Minor) {
164
165 EmitAMDGPUNote(
166 MCConstantExpr::create(8, getContext()),
Yaxun Liu874d26a2017-03-10 19:35:43 +0000167 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000168 [&](MCELFStreamer &OS){
169 OS.EmitIntValue(Major, 4);
170 OS.EmitIntValue(Minor, 4);
171 }
172 );
Tom Stellard347ac792015-06-26 21:15:07 +0000173}
174
175void
176AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
177 uint32_t Minor,
178 uint32_t Stepping,
179 StringRef VendorName,
180 StringRef ArchName) {
Tom Stellard347ac792015-06-26 21:15:07 +0000181 uint16_t VendorNameSize = VendorName.size() + 1;
182 uint16_t ArchNameSize = ArchName.size() + 1;
Matt Arsenaultb4493e92017-02-10 02:42:31 +0000183
Tom Stellard347ac792015-06-26 21:15:07 +0000184 unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
Sam Kolton69c8aa22016-12-19 11:43:15 +0000185 sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
186 VendorNameSize + ArchNameSize;
Tom Stellard347ac792015-06-26 21:15:07 +0000187
Sam Kolton69c8aa22016-12-19 11:43:15 +0000188 EmitAMDGPUNote(
189 MCConstantExpr::create(DescSZ, getContext()),
Yaxun Liu874d26a2017-03-10 19:35:43 +0000190 ElfNote::NT_AMDGPU_HSA_ISA,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000191 [&](MCELFStreamer &OS) {
192 OS.EmitIntValue(VendorNameSize, 2);
193 OS.EmitIntValue(ArchNameSize, 2);
194 OS.EmitIntValue(Major, 4);
195 OS.EmitIntValue(Minor, 4);
196 OS.EmitIntValue(Stepping, 4);
197 OS.EmitBytes(VendorName);
198 OS.EmitIntValue(0, 1); // NULL terminate VendorName
199 OS.EmitBytes(ArchName);
200 OS.EmitIntValue(0, 1); // NULL terminte ArchName
201 }
202 );
Tom Stellard347ac792015-06-26 21:15:07 +0000203}
Tom Stellardff7416b2015-06-26 21:58:31 +0000204
205void
206AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
207
208 MCStreamer &OS = getStreamer();
209 OS.PushSection();
Tom Stellardff7416b2015-06-26 21:58:31 +0000210 OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
211 OS.PopSection();
212}
Tom Stellard1e1b05d2015-11-06 11:45:14 +0000213
214void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
215 unsigned Type) {
216 MCSymbolELF *Symbol = cast<MCSymbolELF>(
217 getStreamer().getContext().getOrCreateSymbol(SymbolName));
218 Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
219}
Tom Stellard00f2f912015-12-02 19:47:57 +0000220
221void AMDGPUTargetELFStreamer::EmitAMDGPUHsaModuleScopeGlobal(
222 StringRef GlobalName) {
223
224 MCSymbolELF *Symbol = cast<MCSymbolELF>(
225 getStreamer().getContext().getOrCreateSymbol(GlobalName));
226 Symbol->setType(ELF::STT_OBJECT);
227 Symbol->setBinding(ELF::STB_LOCAL);
228}
229
230void AMDGPUTargetELFStreamer::EmitAMDGPUHsaProgramScopeGlobal(
231 StringRef GlobalName) {
232
233 MCSymbolELF *Symbol = cast<MCSymbolELF>(
234 getStreamer().getContext().getOrCreateSymbol(GlobalName));
235 Symbol->setType(ELF::STT_OBJECT);
236 Symbol->setBinding(ELF::STB_GLOBAL);
237}
Yaxun Liud6fbe652016-11-10 21:18:49 +0000238
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000239bool AMDGPUTargetELFStreamer::EmitCodeObjectMetadata(
240 const FeatureBitset &Features, StringRef YamlString) {
241 auto VerifiedYamlString =
242 CodeObjectMetadataStreamer.toYamlString(Features, YamlString);
243 if (!VerifiedYamlString)
244 return false;
Konstantin Zhuravlyov972948b2017-02-27 07:55:17 +0000245
Yaxun Liud6fbe652016-11-10 21:18:49 +0000246 // Create two labels to mark the beginning and end of the desc field
247 // and a MCExpr to calculate the size of the desc field.
Sam Kolton69c8aa22016-12-19 11:43:15 +0000248 auto &Context = getContext();
Yaxun Liud6fbe652016-11-10 21:18:49 +0000249 auto *DescBegin = Context.createTempSymbol();
250 auto *DescEnd = Context.createTempSymbol();
251 auto *DescSZ = MCBinaryExpr::createSub(
Sam Kolton69c8aa22016-12-19 11:43:15 +0000252 MCSymbolRefExpr::create(DescEnd, Context),
253 MCSymbolRefExpr::create(DescBegin, Context), Context);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000254
Sam Kolton69c8aa22016-12-19 11:43:15 +0000255 EmitAMDGPUNote(
256 DescSZ,
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000257 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_METADATA,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000258 [&](MCELFStreamer &OS) {
259 OS.EmitLabel(DescBegin);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000260 OS.EmitBytes(VerifiedYamlString.get());
Sam Kolton69c8aa22016-12-19 11:43:15 +0000261 OS.EmitLabel(DescEnd);
262 }
263 );
Konstantin Zhuravlyov972948b2017-02-27 07:55:17 +0000264
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000265 return true;
Yaxun Liud6fbe652016-11-10 21:18:49 +0000266}