blob: 7eef5ed6f6608661434fdf22727c1de74ff46aea [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"
Yaxun Liu07d659b2016-12-14 17:16:52 +000030#include "AMDGPURuntimeMD.h"
Tom Stellard347ac792015-06-26 21:15:07 +000031
Yaxun Liud6fbe652016-11-10 21:18:49 +000032namespace llvm {
33#include "AMDGPUPTNote.h"
34}
35
Tom Stellard347ac792015-06-26 21:15:07 +000036using namespace llvm;
Yaxun Liud6fbe652016-11-10 21:18:49 +000037using namespace llvm::AMDGPU;
Tom Stellard347ac792015-06-26 21:15:07 +000038
39AMDGPUTargetStreamer::AMDGPUTargetStreamer(MCStreamer &S)
Yaxun Liud6fbe652016-11-10 21:18:49 +000040 : MCTargetStreamer(S) {}
Tom Stellard347ac792015-06-26 21:15:07 +000041
42//===----------------------------------------------------------------------===//
43// AMDGPUTargetAsmStreamer
44//===----------------------------------------------------------------------===//
45
46AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
47 formatted_raw_ostream &OS)
48 : AMDGPUTargetStreamer(S), OS(OS) { }
49
50void
51AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
52 uint32_t Minor) {
53 OS << "\t.hsa_code_object_version " <<
54 Twine(Major) << "," << Twine(Minor) << '\n';
55}
56
57void
58AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
59 uint32_t Minor,
60 uint32_t Stepping,
61 StringRef VendorName,
62 StringRef ArchName) {
63 OS << "\t.hsa_code_object_isa " <<
64 Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) <<
65 ",\"" << VendorName << "\",\"" << ArchName << "\"\n";
66
67}
68
Tom Stellardff7416b2015-06-26 21:58:31 +000069void
70AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
Sam Koltona2e5c882016-09-09 10:08:02 +000071 OS << "\t.amd_kernel_code_t\n";
72 dumpAmdKernelCode(&Header, OS, "\t\t");
73 OS << "\t.end_amd_kernel_code_t\n";
Tom Stellardff7416b2015-06-26 21:58:31 +000074}
75
Tom Stellard1e1b05d2015-11-06 11:45:14 +000076void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
77 unsigned Type) {
78 switch (Type) {
79 default: llvm_unreachable("Invalid AMDGPU symbol type");
80 case ELF::STT_AMDGPU_HSA_KERNEL:
81 OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ;
82 break;
83 }
84}
85
Tom Stellard00f2f912015-12-02 19:47:57 +000086void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaModuleScopeGlobal(
87 StringRef GlobalName) {
88 OS << "\t.amdgpu_hsa_module_global " << GlobalName << '\n';
89}
90
91void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaProgramScopeGlobal(
92 StringRef GlobalName) {
93 OS << "\t.amdgpu_hsa_program_global " << GlobalName << '\n';
94}
95
Tom Stellard347ac792015-06-26 21:15:07 +000096//===----------------------------------------------------------------------===//
97// AMDGPUTargetELFStreamer
98//===----------------------------------------------------------------------===//
99
100AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
Yaxun Liud6fbe652016-11-10 21:18:49 +0000101 : AMDGPUTargetStreamer(S), Streamer(S) {}
Tom Stellard347ac792015-06-26 21:15:07 +0000102
103MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
104 return static_cast<MCELFStreamer &>(Streamer);
105}
106
107void
108AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
109 uint32_t Minor) {
110 MCStreamer &OS = getStreamer();
Konstantin Zhuravlyov98a3ac72016-10-17 22:40:15 +0000111 MCSectionELF *Note =
Sam Koltonce0aba72016-11-11 13:41:52 +0000112 OS.getContext().getELFSection(PT_NOTE::SectionName, ELF::SHT_NOTE,
Yaxun Liud6fbe652016-11-10 21:18:49 +0000113 ELF::SHF_ALLOC);
Tom Stellard347ac792015-06-26 21:15:07 +0000114
Yaxun Liud6fbe652016-11-10 21:18:49 +0000115 auto NameSZ = sizeof(PT_NOTE::NoteName);
Tom Stellard347ac792015-06-26 21:15:07 +0000116 OS.PushSection();
117 OS.SwitchSection(Note);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000118 OS.EmitIntValue(NameSZ, 4); // namesz
119 OS.EmitIntValue(8, 4); // descz
120 OS.EmitIntValue(PT_NOTE::NT_AMDGPU_HSA_CODE_OBJECT_VERSION, 4); // type
121 OS.EmitBytes(StringRef(PT_NOTE::NoteName, NameSZ)); // name
Konstantin Zhuravlyov521e5ef2016-10-20 18:22:36 +0000122 OS.EmitValueToAlignment(4);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000123 OS.EmitIntValue(Major, 4); // desc
Tom Stellard347ac792015-06-26 21:15:07 +0000124 OS.EmitIntValue(Minor, 4);
125 OS.EmitValueToAlignment(4);
126 OS.PopSection();
127}
128
129void
130AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
131 uint32_t Minor,
132 uint32_t Stepping,
133 StringRef VendorName,
134 StringRef ArchName) {
135 MCStreamer &OS = getStreamer();
Konstantin Zhuravlyov98a3ac72016-10-17 22:40:15 +0000136 MCSectionELF *Note =
Sam Koltonce0aba72016-11-11 13:41:52 +0000137 OS.getContext().getELFSection(PT_NOTE::SectionName, ELF::SHT_NOTE,
Yaxun Liud6fbe652016-11-10 21:18:49 +0000138 ELF::SHF_ALLOC);
Tom Stellard347ac792015-06-26 21:15:07 +0000139
Tom Stellard347ac792015-06-26 21:15:07 +0000140 uint16_t VendorNameSize = VendorName.size() + 1;
141 uint16_t ArchNameSize = ArchName.size() + 1;
142 unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
143 sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
144 VendorNameSize + ArchNameSize;
145
146 OS.PushSection();
147 OS.SwitchSection(Note);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000148 auto NameSZ = sizeof(PT_NOTE::NoteName);
149 OS.EmitIntValue(NameSZ, 4); // namesz
Konstantin Zhuravlyov521e5ef2016-10-20 18:22:36 +0000150 OS.EmitIntValue(DescSZ, 4); // descsz
Yaxun Liud6fbe652016-11-10 21:18:49 +0000151 OS.EmitIntValue(PT_NOTE::NT_AMDGPU_HSA_ISA, 4); // type
152 OS.EmitBytes(StringRef(PT_NOTE::NoteName, NameSZ)); // name
Konstantin Zhuravlyov521e5ef2016-10-20 18:22:36 +0000153 OS.EmitValueToAlignment(4);
154 OS.EmitIntValue(VendorNameSize, 2); // desc
Tom Stellard347ac792015-06-26 21:15:07 +0000155 OS.EmitIntValue(ArchNameSize, 2);
156 OS.EmitIntValue(Major, 4);
157 OS.EmitIntValue(Minor, 4);
158 OS.EmitIntValue(Stepping, 4);
159 OS.EmitBytes(VendorName);
160 OS.EmitIntValue(0, 1); // NULL terminate VendorName
161 OS.EmitBytes(ArchName);
162 OS.EmitIntValue(0, 1); // NULL terminte ArchName
163 OS.EmitValueToAlignment(4);
164 OS.PopSection();
165}
Tom Stellardff7416b2015-06-26 21:58:31 +0000166
167void
168AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
169
170 MCStreamer &OS = getStreamer();
171 OS.PushSection();
Tom Stellardff7416b2015-06-26 21:58:31 +0000172 OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
173 OS.PopSection();
174}
Tom Stellard1e1b05d2015-11-06 11:45:14 +0000175
176void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
177 unsigned Type) {
178 MCSymbolELF *Symbol = cast<MCSymbolELF>(
179 getStreamer().getContext().getOrCreateSymbol(SymbolName));
180 Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
181}
Tom Stellard00f2f912015-12-02 19:47:57 +0000182
183void AMDGPUTargetELFStreamer::EmitAMDGPUHsaModuleScopeGlobal(
184 StringRef GlobalName) {
185
186 MCSymbolELF *Symbol = cast<MCSymbolELF>(
187 getStreamer().getContext().getOrCreateSymbol(GlobalName));
188 Symbol->setType(ELF::STT_OBJECT);
189 Symbol->setBinding(ELF::STB_LOCAL);
190}
191
192void AMDGPUTargetELFStreamer::EmitAMDGPUHsaProgramScopeGlobal(
193 StringRef GlobalName) {
194
195 MCSymbolELF *Symbol = cast<MCSymbolELF>(
196 getStreamer().getContext().getOrCreateSymbol(GlobalName));
197 Symbol->setType(ELF::STT_OBJECT);
198 Symbol->setBinding(ELF::STB_GLOBAL);
199}
Yaxun Liud6fbe652016-11-10 21:18:49 +0000200
Yaxun Liu07d659b2016-12-14 17:16:52 +0000201void AMDGPUTargetELFStreamer::emitRuntimeMetadata(Module &M) {
Yaxun Liud6fbe652016-11-10 21:18:49 +0000202 auto &S = getStreamer();
203 auto &Context = S.getContext();
204
205 auto NameSZ = sizeof(PT_NOTE::NoteName); // Size of note name including trailing null.
206
207 S.PushSection();
208 S.SwitchSection(Context.getELFSection(
209 PT_NOTE::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
210
211 // Create two labels to mark the beginning and end of the desc field
212 // and a MCExpr to calculate the size of the desc field.
213 auto *DescBegin = Context.createTempSymbol();
214 auto *DescEnd = Context.createTempSymbol();
215 auto *DescSZ = MCBinaryExpr::createSub(
216 MCSymbolRefExpr::create(DescEnd, Context),
217 MCSymbolRefExpr::create(DescBegin, Context), Context);
218
219 // Emit the note element for runtime metadata.
220 // Name and desc should be padded to 4 byte boundary but size of name and
221 // desc should not include padding 0's.
222 S.EmitIntValue(NameSZ, 4); // namesz
223 S.EmitValue(DescSZ, 4); // descz
224 S.EmitIntValue(PT_NOTE::NT_AMDGPU_HSA_RUNTIME_METADATA, 4); // type
225 S.EmitBytes(StringRef(PT_NOTE::NoteName, NameSZ)); // name
Yaxun Liu07d659b2016-12-14 17:16:52 +0000226 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
Yaxun Liud6fbe652016-11-10 21:18:49 +0000227 S.EmitLabel(DescBegin);
Yaxun Liu07d659b2016-12-14 17:16:52 +0000228 S.EmitBytes(getRuntimeMDYAMLString(M)); // desc
Yaxun Liud6fbe652016-11-10 21:18:49 +0000229 S.EmitLabel(DescEnd);
Yaxun Liu07d659b2016-12-14 17:16:52 +0000230 S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
Yaxun Liud6fbe652016-11-10 21:18:49 +0000231 S.PopSection();
232}