blob: 100f1ba84b981a433e688d2cfc52efa4be573527 [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
Konstantin Zhuravlyovca0e7f62017-03-22 22:54:39 +000050void AMDGPUTargetStreamer::EmitKernelCodeObjectMetadata(
51 const Function &Func, const amd_kernel_code_t &KernelCode) {
52 CodeObjectMetadataStreamer.emitKernel(Func, KernelCode);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000053}
54
55void AMDGPUTargetStreamer::EmitEndOfCodeObjectMetadata(
56 const FeatureBitset &Features) {
57 CodeObjectMetadataStreamer.end();
58 EmitCodeObjectMetadata(Features,
59 CodeObjectMetadataStreamer.toYamlString().get());
60}
61
Tom Stellard347ac792015-06-26 21:15:07 +000062//===----------------------------------------------------------------------===//
63// AMDGPUTargetAsmStreamer
64//===----------------------------------------------------------------------===//
65
66AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
67 formatted_raw_ostream &OS)
68 : AMDGPUTargetStreamer(S), OS(OS) { }
69
70void
71AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
72 uint32_t Minor) {
73 OS << "\t.hsa_code_object_version " <<
74 Twine(Major) << "," << Twine(Minor) << '\n';
75}
76
77void
78AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
79 uint32_t Minor,
80 uint32_t Stepping,
81 StringRef VendorName,
82 StringRef ArchName) {
83 OS << "\t.hsa_code_object_isa " <<
84 Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) <<
85 ",\"" << VendorName << "\",\"" << ArchName << "\"\n";
86
87}
88
Tom Stellardff7416b2015-06-26 21:58:31 +000089void
90AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
Sam Koltona2e5c882016-09-09 10:08:02 +000091 OS << "\t.amd_kernel_code_t\n";
92 dumpAmdKernelCode(&Header, OS, "\t\t");
93 OS << "\t.end_amd_kernel_code_t\n";
Tom Stellardff7416b2015-06-26 21:58:31 +000094}
95
Tom Stellard1e1b05d2015-11-06 11:45:14 +000096void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
97 unsigned Type) {
98 switch (Type) {
99 default: llvm_unreachable("Invalid AMDGPU symbol type");
100 case ELF::STT_AMDGPU_HSA_KERNEL:
101 OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ;
102 break;
103 }
104}
105
Tom Stellard00f2f912015-12-02 19:47:57 +0000106void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaModuleScopeGlobal(
107 StringRef GlobalName) {
108 OS << "\t.amdgpu_hsa_module_global " << GlobalName << '\n';
109}
110
111void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaProgramScopeGlobal(
112 StringRef GlobalName) {
113 OS << "\t.amdgpu_hsa_program_global " << GlobalName << '\n';
114}
115
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000116bool AMDGPUTargetAsmStreamer::EmitCodeObjectMetadata(
117 const FeatureBitset &Features, StringRef YamlString) {
118 auto VerifiedYamlString =
119 CodeObjectMetadataStreamer.toYamlString(Features, YamlString);
120 if (!VerifiedYamlString)
121 return false;
Sam Kolton69c8aa22016-12-19 11:43:15 +0000122
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000123 OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveBegin << '\n';
124 OS << VerifiedYamlString.get();
125 OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveEnd << '\n';
Konstantin Zhuravlyov972948b2017-02-27 07:55:17 +0000126
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000127 return true;
Sam Kolton69c8aa22016-12-19 11:43:15 +0000128}
129
Tom Stellard347ac792015-06-26 21:15:07 +0000130//===----------------------------------------------------------------------===//
131// AMDGPUTargetELFStreamer
132//===----------------------------------------------------------------------===//
133
134AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
Yaxun Liud6fbe652016-11-10 21:18:49 +0000135 : AMDGPUTargetStreamer(S), Streamer(S) {}
Tom Stellard347ac792015-06-26 21:15:07 +0000136
137MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
138 return static_cast<MCELFStreamer &>(Streamer);
139}
140
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000141void AMDGPUTargetELFStreamer::EmitAMDGPUNote(
Yaxun Liu874d26a2017-03-10 19:35:43 +0000142 const MCExpr *DescSZ, ElfNote::NoteType Type,
Benjamin Kramer061f4a52017-01-13 14:39:03 +0000143 function_ref<void(MCELFStreamer &)> EmitDesc) {
Sam Kolton69c8aa22016-12-19 11:43:15 +0000144 auto &S = getStreamer();
145 auto &Context = S.getContext();
Tom Stellard347ac792015-06-26 21:15:07 +0000146
Yaxun Liu874d26a2017-03-10 19:35:43 +0000147 auto NameSZ = sizeof(ElfNote::NoteName);
Sam Kolton69c8aa22016-12-19 11:43:15 +0000148
149 S.PushSection();
150 S.SwitchSection(Context.getELFSection(
Yaxun Liu874d26a2017-03-10 19:35:43 +0000151 ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
Sam Kolton69c8aa22016-12-19 11:43:15 +0000152 S.EmitIntValue(NameSZ, 4); // namesz
153 S.EmitValue(DescSZ, 4); // descz
Yaxun Liu874d26a2017-03-10 19:35:43 +0000154 S.EmitIntValue(Type, 4); // type
155 S.EmitBytes(StringRef(ElfNote::NoteName, NameSZ)); // name
Sam Kolton69c8aa22016-12-19 11:43:15 +0000156 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
157 EmitDesc(S); // desc
158 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
159 S.PopSection();
160}
161
162void
163AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
164 uint32_t Minor) {
165
166 EmitAMDGPUNote(
167 MCConstantExpr::create(8, getContext()),
Yaxun Liu874d26a2017-03-10 19:35:43 +0000168 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000169 [&](MCELFStreamer &OS){
170 OS.EmitIntValue(Major, 4);
171 OS.EmitIntValue(Minor, 4);
172 }
173 );
Tom Stellard347ac792015-06-26 21:15:07 +0000174}
175
176void
177AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
178 uint32_t Minor,
179 uint32_t Stepping,
180 StringRef VendorName,
181 StringRef ArchName) {
Tom Stellard347ac792015-06-26 21:15:07 +0000182 uint16_t VendorNameSize = VendorName.size() + 1;
183 uint16_t ArchNameSize = ArchName.size() + 1;
Matt Arsenaultb4493e92017-02-10 02:42:31 +0000184
Tom Stellard347ac792015-06-26 21:15:07 +0000185 unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
Sam Kolton69c8aa22016-12-19 11:43:15 +0000186 sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
187 VendorNameSize + ArchNameSize;
Tom Stellard347ac792015-06-26 21:15:07 +0000188
Sam Kolton69c8aa22016-12-19 11:43:15 +0000189 EmitAMDGPUNote(
190 MCConstantExpr::create(DescSZ, getContext()),
Yaxun Liu874d26a2017-03-10 19:35:43 +0000191 ElfNote::NT_AMDGPU_HSA_ISA,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000192 [&](MCELFStreamer &OS) {
193 OS.EmitIntValue(VendorNameSize, 2);
194 OS.EmitIntValue(ArchNameSize, 2);
195 OS.EmitIntValue(Major, 4);
196 OS.EmitIntValue(Minor, 4);
197 OS.EmitIntValue(Stepping, 4);
198 OS.EmitBytes(VendorName);
199 OS.EmitIntValue(0, 1); // NULL terminate VendorName
200 OS.EmitBytes(ArchName);
201 OS.EmitIntValue(0, 1); // NULL terminte ArchName
202 }
203 );
Tom Stellard347ac792015-06-26 21:15:07 +0000204}
Tom Stellardff7416b2015-06-26 21:58:31 +0000205
206void
207AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
208
209 MCStreamer &OS = getStreamer();
210 OS.PushSection();
Tom Stellardff7416b2015-06-26 21:58:31 +0000211 OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
212 OS.PopSection();
213}
Tom Stellard1e1b05d2015-11-06 11:45:14 +0000214
215void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
216 unsigned Type) {
217 MCSymbolELF *Symbol = cast<MCSymbolELF>(
218 getStreamer().getContext().getOrCreateSymbol(SymbolName));
219 Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
220}
Tom Stellard00f2f912015-12-02 19:47:57 +0000221
222void AMDGPUTargetELFStreamer::EmitAMDGPUHsaModuleScopeGlobal(
223 StringRef GlobalName) {
224
225 MCSymbolELF *Symbol = cast<MCSymbolELF>(
226 getStreamer().getContext().getOrCreateSymbol(GlobalName));
227 Symbol->setType(ELF::STT_OBJECT);
228 Symbol->setBinding(ELF::STB_LOCAL);
229}
230
231void AMDGPUTargetELFStreamer::EmitAMDGPUHsaProgramScopeGlobal(
232 StringRef GlobalName) {
233
234 MCSymbolELF *Symbol = cast<MCSymbolELF>(
235 getStreamer().getContext().getOrCreateSymbol(GlobalName));
236 Symbol->setType(ELF::STT_OBJECT);
237 Symbol->setBinding(ELF::STB_GLOBAL);
238}
Yaxun Liud6fbe652016-11-10 21:18:49 +0000239
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000240bool AMDGPUTargetELFStreamer::EmitCodeObjectMetadata(
241 const FeatureBitset &Features, StringRef YamlString) {
242 auto VerifiedYamlString =
243 CodeObjectMetadataStreamer.toYamlString(Features, YamlString);
244 if (!VerifiedYamlString)
245 return false;
Konstantin Zhuravlyov972948b2017-02-27 07:55:17 +0000246
Yaxun Liud6fbe652016-11-10 21:18:49 +0000247 // Create two labels to mark the beginning and end of the desc field
248 // and a MCExpr to calculate the size of the desc field.
Sam Kolton69c8aa22016-12-19 11:43:15 +0000249 auto &Context = getContext();
Yaxun Liud6fbe652016-11-10 21:18:49 +0000250 auto *DescBegin = Context.createTempSymbol();
251 auto *DescEnd = Context.createTempSymbol();
252 auto *DescSZ = MCBinaryExpr::createSub(
Sam Kolton69c8aa22016-12-19 11:43:15 +0000253 MCSymbolRefExpr::create(DescEnd, Context),
254 MCSymbolRefExpr::create(DescBegin, Context), Context);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000255
Sam Kolton69c8aa22016-12-19 11:43:15 +0000256 EmitAMDGPUNote(
257 DescSZ,
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000258 ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_METADATA,
Sam Kolton69c8aa22016-12-19 11:43:15 +0000259 [&](MCELFStreamer &OS) {
260 OS.EmitLabel(DescBegin);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000261 OS.EmitBytes(VerifiedYamlString.get());
Sam Kolton69c8aa22016-12-19 11:43:15 +0000262 OS.EmitLabel(DescEnd);
263 }
264 );
Konstantin Zhuravlyov972948b2017-02-27 07:55:17 +0000265
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000266 return true;
Yaxun Liud6fbe652016-11-10 21:18:49 +0000267}