AMDGPUTargetStreamer.cpp revision 360784
1139804Simp//===-- AMDGPUTargetStreamer.cpp - Mips Target Streamer Methods -----------===//
2139013Sdavidxu//
3112904Sjeff// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4112904Sjeff// See https://llvm.org/LICENSE.txt for license information.
5112904Sjeff// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6112904Sjeff//
7112904Sjeff//===----------------------------------------------------------------------===//
8112904Sjeff//
9112904Sjeff// This file provides AMDGPU specific target streamer methods.
10112904Sjeff//
11112904Sjeff//===----------------------------------------------------------------------===//
12112904Sjeff
13112904Sjeff#include "AMDGPUTargetStreamer.h"
14112904Sjeff#include "AMDGPU.h"
15112904Sjeff#include "SIDefines.h"
16112904Sjeff#include "Utils/AMDGPUBaseInfo.h"
17112904Sjeff#include "Utils/AMDKernelCodeTUtils.h"
18112904Sjeff#include "llvm/ADT/Twine.h"
19112904Sjeff#include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h"
20112904Sjeff#include "llvm/BinaryFormat/ELF.h"
21112904Sjeff#include "llvm/IR/Constants.h"
22112904Sjeff#include "llvm/IR/Function.h"
23112904Sjeff#include "llvm/IR/Metadata.h"
24112904Sjeff#include "llvm/IR/Module.h"
25112904Sjeff#include "llvm/MC/MCContext.h"
26112904Sjeff#include "llvm/MC/MCELFStreamer.h"
27112904Sjeff#include "llvm/MC/MCObjectFileInfo.h"
28116182Sobrien#include "llvm/MC/MCSectionELF.h"
29116182Sobrien#include "llvm/Support/FormattedStream.h"
30116182Sobrien#include "llvm/Support/TargetParser.h"
31162536Sdavidxu
32112904Sjeffnamespace llvm {
33112904Sjeff#include "AMDGPUPTNote.h"
34131431Smarcel}
35112904Sjeff
36115765Sjeffusing namespace llvm;
37112904Sjeffusing namespace llvm::AMDGPU;
38164033Srwatsonusing namespace llvm::AMDGPU::HSAMD;
39112904Sjeff
40161678Sdavidxu//===----------------------------------------------------------------------===//
41165369Sdavidxu// AMDGPUTargetStreamer
42161678Sdavidxu//===----------------------------------------------------------------------===//
43112904Sjeff
44112904Sjeffbool AMDGPUTargetStreamer::EmitHSAMetadataV2(StringRef HSAMetadataString) {
45112904Sjeff  HSAMD::Metadata HSAMetadata;
46139013Sdavidxu  if (HSAMD::fromString(HSAMetadataString, HSAMetadata))
47112904Sjeff    return false;
48112904Sjeff
49139013Sdavidxu  return EmitHSAMetadata(HSAMetadata);
50139013Sdavidxu}
51139013Sdavidxu
52139013Sdavidxubool AMDGPUTargetStreamer::EmitHSAMetadataV3(StringRef HSAMetadataString) {
53139013Sdavidxu  msgpack::Document HSAMetadataDoc;
54139013Sdavidxu  if (!HSAMetadataDoc.fromYAML(HSAMetadataString))
55165369Sdavidxu    return false;
56165369Sdavidxu  return EmitHSAMetadata(HSAMetadataDoc, false);
57162536Sdavidxu}
58162536Sdavidxu
59162536SdavidxuStringRef AMDGPUTargetStreamer::getArchNameFromElfMach(unsigned ElfMach) {
60162536Sdavidxu  AMDGPU::GPUKind AK;
61179421Sdavidxu
62179421Sdavidxu  switch (ElfMach) {
63179421Sdavidxu  default: llvm_unreachable("Unhandled ELF::EF_AMDGPU type");
64179421Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_R600:      AK = GK_R600;    break;
65179421Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_R630:      AK = GK_R630;    break;
66179421Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_RS880:     AK = GK_RS880;   break;
67177848Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_RV670:     AK = GK_RV670;   break;
68139013Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_RV710:     AK = GK_RV710;   break;
69179970Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_RV730:     AK = GK_RV730;   break;
70179970Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_RV770:     AK = GK_RV770;   break;
71179970Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_CEDAR:     AK = GK_CEDAR;   break;
72161678Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_CYPRESS:   AK = GK_CYPRESS; break;
73139013Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_JUNIPER:   AK = GK_JUNIPER; break;
74161678Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_REDWOOD:   AK = GK_REDWOOD; break;
75139013Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_SUMO:      AK = GK_SUMO;    break;
76161678Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_BARTS:     AK = GK_BARTS;   break;
77139013Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_CAICOS:    AK = GK_CAICOS;  break;
78139013Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_CAYMAN:    AK = GK_CAYMAN;  break;
79139013Sdavidxu  case ELF::EF_AMDGPU_MACH_R600_TURKS:     AK = GK_TURKS;   break;
80161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600:  AK = GK_GFX600;  break;
81139013Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601:  AK = GK_GFX601;  break;
82139013Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700:  AK = GK_GFX700;  break;
83161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701:  AK = GK_GFX701;  break;
84161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702:  AK = GK_GFX702;  break;
85139013Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703:  AK = GK_GFX703;  break;
86139013Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704:  AK = GK_GFX704;  break;
87161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801:  AK = GK_GFX801;  break;
88161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802:  AK = GK_GFX802;  break;
89139013Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803:  AK = GK_GFX803;  break;
90139013Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810:  AK = GK_GFX810;  break;
91139013Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900:  AK = GK_GFX900;  break;
92139013Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902:  AK = GK_GFX902;  break;
93161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904:  AK = GK_GFX904;  break;
94161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906:  AK = GK_GFX906;  break;
95161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908:  AK = GK_GFX908;  break;
96161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909:  AK = GK_GFX909;  break;
97161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010: AK = GK_GFX1010; break;
98161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011: AK = GK_GFX1011; break;
99161678Sdavidxu  case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012: AK = GK_GFX1012; break;
100161678Sdavidxu  case ELF::EF_AMDGPU_MACH_NONE:           AK = GK_NONE;    break;
101161678Sdavidxu  }
102161678Sdavidxu
103161678Sdavidxu  StringRef GPUName = getArchNameAMDGCN(AK);
104161678Sdavidxu  if (GPUName != "")
105161678Sdavidxu    return GPUName;
106161678Sdavidxu  return getArchNameR600(AK);
107161678Sdavidxu}
108161678Sdavidxu
109161678Sdavidxuunsigned AMDGPUTargetStreamer::getElfMach(StringRef GPU) {
110161678Sdavidxu  AMDGPU::GPUKind AK = parseArchAMDGCN(GPU);
111161678Sdavidxu  if (AK == AMDGPU::GPUKind::GK_NONE)
112161678Sdavidxu    AK = parseArchR600(GPU);
113161678Sdavidxu
114161678Sdavidxu  switch (AK) {
115115765Sjeff  case GK_R600:    return ELF::EF_AMDGPU_MACH_R600_R600;
116161678Sdavidxu  case GK_R630:    return ELF::EF_AMDGPU_MACH_R600_R630;
117161678Sdavidxu  case GK_RS880:   return ELF::EF_AMDGPU_MACH_R600_RS880;
118161678Sdavidxu  case GK_RV670:   return ELF::EF_AMDGPU_MACH_R600_RV670;
119161678Sdavidxu  case GK_RV710:   return ELF::EF_AMDGPU_MACH_R600_RV710;
120161678Sdavidxu  case GK_RV730:   return ELF::EF_AMDGPU_MACH_R600_RV730;
121161678Sdavidxu  case GK_RV770:   return ELF::EF_AMDGPU_MACH_R600_RV770;
122161678Sdavidxu  case GK_CEDAR:   return ELF::EF_AMDGPU_MACH_R600_CEDAR;
123161678Sdavidxu  case GK_CYPRESS: return ELF::EF_AMDGPU_MACH_R600_CYPRESS;
124161678Sdavidxu  case GK_JUNIPER: return ELF::EF_AMDGPU_MACH_R600_JUNIPER;
125161678Sdavidxu  case GK_REDWOOD: return ELF::EF_AMDGPU_MACH_R600_REDWOOD;
126161678Sdavidxu  case GK_SUMO:    return ELF::EF_AMDGPU_MACH_R600_SUMO;
127161678Sdavidxu  case GK_BARTS:   return ELF::EF_AMDGPU_MACH_R600_BARTS;
128161678Sdavidxu  case GK_CAICOS:  return ELF::EF_AMDGPU_MACH_R600_CAICOS;
129161678Sdavidxu  case GK_CAYMAN:  return ELF::EF_AMDGPU_MACH_R600_CAYMAN;
130161678Sdavidxu  case GK_TURKS:   return ELF::EF_AMDGPU_MACH_R600_TURKS;
131170300Sjeff  case GK_GFX600:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX600;
132170300Sjeff  case GK_GFX601:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX601;
133161678Sdavidxu  case GK_GFX700:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX700;
134161678Sdavidxu  case GK_GFX701:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX701;
135161678Sdavidxu  case GK_GFX702:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX702;
136161678Sdavidxu  case GK_GFX703:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX703;
137161678Sdavidxu  case GK_GFX704:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX704;
138161678Sdavidxu  case GK_GFX801:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX801;
139161678Sdavidxu  case GK_GFX802:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX802;
140161678Sdavidxu  case GK_GFX803:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX803;
141161678Sdavidxu  case GK_GFX810:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX810;
142161742Sdavidxu  case GK_GFX900:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX900;
143161678Sdavidxu  case GK_GFX902:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX902;
144115765Sjeff  case GK_GFX904:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX904;
145115765Sjeff  case GK_GFX906:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX906;
146161678Sdavidxu  case GK_GFX908:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX908;
147161678Sdavidxu  case GK_GFX909:  return ELF::EF_AMDGPU_MACH_AMDGCN_GFX909;
148161678Sdavidxu  case GK_GFX1010: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010;
149138224Sdavidxu  case GK_GFX1011: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011;
150161678Sdavidxu  case GK_GFX1012: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012;
151161678Sdavidxu  case GK_NONE:    return ELF::EF_AMDGPU_MACH_NONE;
152161678Sdavidxu  }
153161678Sdavidxu
154177848Sdavidxu  llvm_unreachable("unknown GPU");
155177848Sdavidxu}
156177848Sdavidxu
157161678Sdavidxu//===----------------------------------------------------------------------===//
158161678Sdavidxu// AMDGPUTargetAsmStreamer
159161678Sdavidxu//===----------------------------------------------------------------------===//
160161678Sdavidxu
161161678SdavidxuAMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
162158377Sdavidxu                                                 formatted_raw_ostream &OS)
163161678Sdavidxu    : AMDGPUTargetStreamer(S), OS(OS) { }
164161678Sdavidxu
165161678Sdavidxu// A hook for emitting stuff at the end.
166138224Sdavidxu// We use it for emitting the accumulated PAL metadata as directives.
167115765Sjeffvoid AMDGPUTargetAsmStreamer::finish() {
168161678Sdavidxu  std::string S;
169161678Sdavidxu  getPALMetadata()->toString(S);
170161678Sdavidxu  OS << S;
171161678Sdavidxu}
172161678Sdavidxu
173161678Sdavidxuvoid AMDGPUTargetAsmStreamer::EmitDirectiveAMDGCNTarget(StringRef Target) {
174161678Sdavidxu  OS << "\t.amdgcn_target \"" << Target << "\"\n";
175161678Sdavidxu}
176161678Sdavidxu
177161678Sdavidxuvoid AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(
178161678Sdavidxu    uint32_t Major, uint32_t Minor) {
179163709Sjb  OS << "\t.hsa_code_object_version " <<
180163709Sjb        Twine(Major) << "," << Twine(Minor) << '\n';
181163709Sjb}
182161678Sdavidxu
183138224Sdavidxuvoid
184138224SdavidxuAMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
185138224Sdavidxu                                                       uint32_t Minor,
186115765Sjeff                                                       uint32_t Stepping,
187161678Sdavidxu                                                       StringRef VendorName,
188161678Sdavidxu                                                       StringRef ArchName) {
189161678Sdavidxu  OS << "\t.hsa_code_object_isa " <<
190161678Sdavidxu        Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) <<
191161678Sdavidxu        ",\"" << VendorName << "\",\"" << ArchName << "\"\n";
192161678Sdavidxu
193161678Sdavidxu}
194177848Sdavidxu
195177848Sdavidxuvoid
196161678SdavidxuAMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
197179421Sdavidxu  OS << "\t.amd_kernel_code_t\n";
198138224Sdavidxu  dumpAmdKernelCode(&Header, OS, "\t\t");
199161678Sdavidxu  OS << "\t.end_amd_kernel_code_t\n";
200115310Sjeff}
201161678Sdavidxu
202161678Sdavidxuvoid AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
203161678Sdavidxu                                                   unsigned Type) {
204161678Sdavidxu  switch (Type) {
205161678Sdavidxu    default: llvm_unreachable("Invalid AMDGPU symbol type");
206161678Sdavidxu    case ELF::STT_AMDGPU_HSA_KERNEL:
207161678Sdavidxu      OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ;
208139013Sdavidxu      break;
209139013Sdavidxu  }
210139257Sdavidxu}
211139257Sdavidxu
212177848Sdavidxuvoid AMDGPUTargetAsmStreamer::emitAMDGPULDS(MCSymbol *Symbol, unsigned Size,
213177848Sdavidxu                                            unsigned Align) {
214161678Sdavidxu  OS << "\t.amdgpu_lds " << Symbol->getName() << ", " << Size << ", " << Align
215139257Sdavidxu     << '\n';
216139013Sdavidxu}
217161678Sdavidxu
218139013Sdavidxubool AMDGPUTargetAsmStreamer::EmitISAVersion(StringRef IsaVersionString) {
219139013Sdavidxu  OS << "\t.amd_amdgpu_isa \"" << IsaVersionString << "\"\n";
220163697Sdavidxu  return true;
221161678Sdavidxu}
222174701Sdavidxu
223161678Sdavidxubool AMDGPUTargetAsmStreamer::EmitHSAMetadata(
224161678Sdavidxu    const AMDGPU::HSAMD::Metadata &HSAMetadata) {
225161678Sdavidxu  std::string HSAMetadataString;
226161678Sdavidxu  if (HSAMD::toString(HSAMetadata, HSAMetadataString))
227161678Sdavidxu    return false;
228115310Sjeff
229177848Sdavidxu  OS << '\t' << AssemblerDirectiveBegin << '\n';
230177848Sdavidxu  OS << HSAMetadataString << '\n';
231177848Sdavidxu  OS << '\t' << AssemblerDirectiveEnd << '\n';
232177848Sdavidxu  return true;
233170300Sjeff}
234170300Sjeff
235161678Sdavidxubool AMDGPUTargetAsmStreamer::EmitHSAMetadata(
236161678Sdavidxu    msgpack::Document &HSAMetadataDoc, bool Strict) {
237161678Sdavidxu  V3::MetadataVerifier Verifier(Strict);
238179421Sdavidxu  if (!Verifier.verify(HSAMetadataDoc.getRoot()))
239138224Sdavidxu    return false;
240161678Sdavidxu
241161678Sdavidxu  std::string HSAMetadataString;
242179421Sdavidxu  raw_string_ostream StrOS(HSAMetadataString);
243179421Sdavidxu  HSAMetadataDoc.toYAML(StrOS);
244179421Sdavidxu
245179421Sdavidxu  OS << '\t' << V3::AssemblerDirectiveBegin << '\n';
246179421Sdavidxu  OS << StrOS.str() << '\n';
247179421Sdavidxu  OS << '\t' << V3::AssemblerDirectiveEnd << '\n';
248179421Sdavidxu  return true;
249179421Sdavidxu}
250179421Sdavidxu
251179421Sdavidxubool AMDGPUTargetAsmStreamer::EmitCodeEnd() {
252161678Sdavidxu  const uint32_t Encoded_s_code_end = 0xbf9f0000;
253170300Sjeff  OS << "\t.p2alignl 6, " << Encoded_s_code_end << '\n';
254161678Sdavidxu  OS << "\t.fill 48, 4, " << Encoded_s_code_end << '\n';
255161678Sdavidxu  return true;
256161678Sdavidxu}
257161678Sdavidxu
258143149Sdavidxuvoid AMDGPUTargetAsmStreamer::EmitAmdhsaKernelDescriptor(
259143149Sdavidxu    const MCSubtargetInfo &STI, StringRef KernelName,
260143149Sdavidxu    const amdhsa::kernel_descriptor_t &KD, uint64_t NextVGPR, uint64_t NextSGPR,
261161678Sdavidxu    bool ReserveVCC, bool ReserveFlatScr, bool ReserveXNACK) {
262161678Sdavidxu  IsaVersion IVersion = getIsaVersion(STI.getCPU());
263161678Sdavidxu
264161678Sdavidxu  OS << "\t.amdhsa_kernel " << KernelName << '\n';
265161678Sdavidxu
266161678Sdavidxu#define PRINT_FIELD(STREAM, DIRECTIVE, KERNEL_DESC, MEMBER_NAME, FIELD_NAME)   \
267143149Sdavidxu  STREAM << "\t\t" << DIRECTIVE << " "                                         \
268143149Sdavidxu         << AMDHSA_BITS_GET(KERNEL_DESC.MEMBER_NAME, FIELD_NAME) << '\n';
269143149Sdavidxu
270143149Sdavidxu  OS << "\t\t.amdhsa_group_segment_fixed_size " << KD.group_segment_fixed_size
271143149Sdavidxu     << '\n';
272143149Sdavidxu  OS << "\t\t.amdhsa_private_segment_fixed_size "
273143149Sdavidxu     << KD.private_segment_fixed_size << '\n';
274143149Sdavidxu
275161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_user_sgpr_private_segment_buffer", KD,
276139013Sdavidxu              kernel_code_properties,
277138224Sdavidxu              amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER);
278161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_user_sgpr_dispatch_ptr", KD,
279161678Sdavidxu              kernel_code_properties,
280138224Sdavidxu              amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR);
281138224Sdavidxu  PRINT_FIELD(OS, ".amdhsa_user_sgpr_queue_ptr", KD,
282139013Sdavidxu              kernel_code_properties,
283139013Sdavidxu              amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR);
284139013Sdavidxu  PRINT_FIELD(OS, ".amdhsa_user_sgpr_kernarg_segment_ptr", KD,
285139013Sdavidxu              kernel_code_properties,
286161678Sdavidxu              amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR);
287161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_user_sgpr_dispatch_id", KD,
288139013Sdavidxu              kernel_code_properties,
289139013Sdavidxu              amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID);
290161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_user_sgpr_flat_scratch_init", KD,
291161678Sdavidxu              kernel_code_properties,
292139013Sdavidxu              amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT);
293179421Sdavidxu  PRINT_FIELD(OS, ".amdhsa_user_sgpr_private_segment_size", KD,
294179421Sdavidxu              kernel_code_properties,
295179421Sdavidxu              amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE);
296139013Sdavidxu  if (IVersion.Major >= 10)
297139013Sdavidxu    PRINT_FIELD(OS, ".amdhsa_wavefront_size32", KD,
298161678Sdavidxu                kernel_code_properties,
299177848Sdavidxu                amdhsa::KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32);
300161678Sdavidxu  PRINT_FIELD(
301138224Sdavidxu      OS, ".amdhsa_system_sgpr_private_segment_wavefront_offset", KD,
302177848Sdavidxu      compute_pgm_rsrc2,
303139257Sdavidxu      amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_PRIVATE_SEGMENT_WAVEFRONT_OFFSET);
304161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_system_sgpr_workgroup_id_x", KD,
305139257Sdavidxu              compute_pgm_rsrc2,
306161678Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X);
307177848Sdavidxu  PRINT_FIELD(OS, ".amdhsa_system_sgpr_workgroup_id_y", KD,
308139257Sdavidxu              compute_pgm_rsrc2,
309139257Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y);
310161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_system_sgpr_workgroup_id_z", KD,
311177848Sdavidxu              compute_pgm_rsrc2,
312161678Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z);
313139257Sdavidxu  PRINT_FIELD(OS, ".amdhsa_system_sgpr_workgroup_info", KD,
314177848Sdavidxu              compute_pgm_rsrc2,
315139257Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO);
316161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_system_vgpr_workitem_id", KD,
317139257Sdavidxu              compute_pgm_rsrc2,
318161678Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID);
319177848Sdavidxu
320139257Sdavidxu  // These directives are required.
321139257Sdavidxu  OS << "\t\t.amdhsa_next_free_vgpr " << NextVGPR << '\n';
322161678Sdavidxu  OS << "\t\t.amdhsa_next_free_sgpr " << NextSGPR << '\n';
323177848Sdavidxu
324177848Sdavidxu  if (!ReserveVCC)
325161678Sdavidxu    OS << "\t\t.amdhsa_reserve_vcc " << ReserveVCC << '\n';
326139257Sdavidxu  if (IVersion.Major >= 7 && !ReserveFlatScr)
327177848Sdavidxu    OS << "\t\t.amdhsa_reserve_flat_scratch " << ReserveFlatScr << '\n';
328138224Sdavidxu  if (IVersion.Major >= 8 && ReserveXNACK != hasXNACK(STI))
329161678Sdavidxu    OS << "\t\t.amdhsa_reserve_xnack_mask " << ReserveXNACK << '\n';
330161678Sdavidxu
331161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_float_round_mode_32", KD,
332177848Sdavidxu              compute_pgm_rsrc1,
333177848Sdavidxu              amdhsa::COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32);
334177880Sdavidxu  PRINT_FIELD(OS, ".amdhsa_float_round_mode_16_64", KD,
335177880Sdavidxu              compute_pgm_rsrc1,
336177880Sdavidxu              amdhsa::COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64);
337177880Sdavidxu  PRINT_FIELD(OS, ".amdhsa_float_denorm_mode_32", KD,
338177880Sdavidxu              compute_pgm_rsrc1,
339177880Sdavidxu              amdhsa::COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32);
340177880Sdavidxu  PRINT_FIELD(OS, ".amdhsa_float_denorm_mode_16_64", KD,
341177880Sdavidxu              compute_pgm_rsrc1,
342177880Sdavidxu              amdhsa::COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64);
343177848Sdavidxu  PRINT_FIELD(OS, ".amdhsa_dx10_clamp", KD,
344177880Sdavidxu              compute_pgm_rsrc1,
345177880Sdavidxu              amdhsa::COMPUTE_PGM_RSRC1_ENABLE_DX10_CLAMP);
346177848Sdavidxu  PRINT_FIELD(OS, ".amdhsa_ieee_mode", KD,
347177848Sdavidxu              compute_pgm_rsrc1,
348177848Sdavidxu              amdhsa::COMPUTE_PGM_RSRC1_ENABLE_IEEE_MODE);
349177848Sdavidxu  if (IVersion.Major >= 9)
350177848Sdavidxu    PRINT_FIELD(OS, ".amdhsa_fp16_overflow", KD,
351177848Sdavidxu                compute_pgm_rsrc1,
352138224Sdavidxu                amdhsa::COMPUTE_PGM_RSRC1_FP16_OVFL);
353138224Sdavidxu  if (IVersion.Major >= 10) {
354161678Sdavidxu    PRINT_FIELD(OS, ".amdhsa_workgroup_processor_mode", KD,
355177848Sdavidxu                compute_pgm_rsrc1,
356161678Sdavidxu                amdhsa::COMPUTE_PGM_RSRC1_WGP_MODE);
357138225Sdavidxu    PRINT_FIELD(OS, ".amdhsa_memory_ordered", KD,
358177848Sdavidxu                compute_pgm_rsrc1,
359138224Sdavidxu                amdhsa::COMPUTE_PGM_RSRC1_MEM_ORDERED);
360161678Sdavidxu    PRINT_FIELD(OS, ".amdhsa_forward_progress", KD,
361161678Sdavidxu                compute_pgm_rsrc1,
362161678Sdavidxu                amdhsa::COMPUTE_PGM_RSRC1_FWD_PROGRESS);
363177848Sdavidxu  }
364177848Sdavidxu  PRINT_FIELD(
365177848Sdavidxu      OS, ".amdhsa_exception_fp_ieee_invalid_op", KD,
366177848Sdavidxu      compute_pgm_rsrc2,
367177848Sdavidxu      amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION);
368138224Sdavidxu  PRINT_FIELD(OS, ".amdhsa_exception_fp_denorm_src", KD,
369138224Sdavidxu              compute_pgm_rsrc2,
370139013Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE);
371177848Sdavidxu  PRINT_FIELD(
372115765Sjeff      OS, ".amdhsa_exception_fp_ieee_div_zero", KD,
373161678Sdavidxu      compute_pgm_rsrc2,
374139013Sdavidxu      amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO);
375161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_exception_fp_ieee_overflow", KD,
376161678Sdavidxu              compute_pgm_rsrc2,
377177848Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW);
378158718Sdavidxu  PRINT_FIELD(OS, ".amdhsa_exception_fp_ieee_underflow", KD,
379139013Sdavidxu              compute_pgm_rsrc2,
380139013Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW);
381139013Sdavidxu  PRINT_FIELD(OS, ".amdhsa_exception_fp_ieee_inexact", KD,
382177848Sdavidxu              compute_pgm_rsrc2,
383139013Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT);
384161678Sdavidxu  PRINT_FIELD(OS, ".amdhsa_exception_int_div_zero", KD,
385161678Sdavidxu              compute_pgm_rsrc2,
386161678Sdavidxu              amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO);
387161678Sdavidxu#undef PRINT_FIELD
388158718Sdavidxu
389177848Sdavidxu  OS << "\t.end_amdhsa_kernel\n";
390158718Sdavidxu}
391139013Sdavidxu
392139013Sdavidxu//===----------------------------------------------------------------------===//
393139013Sdavidxu// AMDGPUTargetELFStreamer
394161678Sdavidxu//===----------------------------------------------------------------------===//
395161678Sdavidxu
396161678SdavidxuAMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(
397139013Sdavidxu    MCStreamer &S, const MCSubtargetInfo &STI)
398139013Sdavidxu    : AMDGPUTargetStreamer(S), Streamer(S) {
399139013Sdavidxu  MCAssembler &MCA = getStreamer().getAssembler();
400161678Sdavidxu  unsigned EFlags = MCA.getELFHeaderEFlags();
401115765Sjeff
402161678Sdavidxu  EFlags &= ~ELF::EF_AMDGPU_MACH;
403115765Sjeff  EFlags |= getElfMach(STI.getCPU());
404161678Sdavidxu
405161678Sdavidxu  EFlags &= ~ELF::EF_AMDGPU_XNACK;
406177848Sdavidxu  if (AMDGPU::hasXNACK(STI))
407139013Sdavidxu    EFlags |= ELF::EF_AMDGPU_XNACK;
408139013Sdavidxu
409139013Sdavidxu  EFlags &= ~ELF::EF_AMDGPU_SRAM_ECC;
410139013Sdavidxu  if (AMDGPU::hasSRAMECC(STI))
411115765Sjeff    EFlags |= ELF::EF_AMDGPU_SRAM_ECC;
412139013Sdavidxu
413115765Sjeff  MCA.setELFHeaderEFlags(EFlags);
414115765Sjeff}
415161678Sdavidxu
416161678SdavidxuMCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
417161678Sdavidxu  return static_cast<MCELFStreamer &>(Streamer);
418161678Sdavidxu}
419139257Sdavidxu
420161678Sdavidxu// A hook for emitting stuff at the end.
421161678Sdavidxu// We use it for emitting the accumulated PAL metadata as a .note record.
422161678Sdavidxuvoid AMDGPUTargetELFStreamer::finish() {
423161678Sdavidxu  std::string Blob;
424161678Sdavidxu  const char *Vendor = getPALMetadata()->getVendor();
425161678Sdavidxu  unsigned Type = getPALMetadata()->getType();
426161678Sdavidxu  getPALMetadata()->toBlob(Type, Blob);
427161678Sdavidxu  if (Blob.empty())
428161678Sdavidxu    return;
429177848Sdavidxu  EmitNote(Vendor, MCConstantExpr::create(Blob.size(), getContext()), Type,
430161678Sdavidxu           [&](MCELFStreamer &OS) { OS.EmitBytes(Blob); });
431161678Sdavidxu}
432161678Sdavidxu
433161678Sdavidxuvoid AMDGPUTargetELFStreamer::EmitNote(
434161678Sdavidxu    StringRef Name, const MCExpr *DescSZ, unsigned NoteType,
435161678Sdavidxu    function_ref<void(MCELFStreamer &)> EmitDesc) {
436161678Sdavidxu  auto &S = getStreamer();
437161678Sdavidxu  auto &Context = S.getContext();
438161678Sdavidxu
439161678Sdavidxu  auto NameSZ = Name.size() + 1;
440161678Sdavidxu
441161678Sdavidxu  S.PushSection();
442177848Sdavidxu  S.SwitchSection(Context.getELFSection(
443161678Sdavidxu    ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
444177848Sdavidxu  S.EmitIntValue(NameSZ, 4);                                  // namesz
445115765Sjeff  S.EmitValue(DescSZ, 4);                                     // descz
446161678Sdavidxu  S.EmitIntValue(NoteType, 4);                                // type
447139257Sdavidxu  S.EmitBytes(Name);                                          // name
448161678Sdavidxu  S.EmitValueToAlignment(4, 0, 1, 0);                         // padding 0
449115765Sjeff  EmitDesc(S);                                                // desc
450139257Sdavidxu  S.EmitValueToAlignment(4, 0, 1, 0);                         // padding 0
451161678Sdavidxu  S.PopSection();
452161678Sdavidxu}
453177848Sdavidxu
454139013Sdavidxuvoid AMDGPUTargetELFStreamer::EmitDirectiveAMDGCNTarget(StringRef Target) {}
455177848Sdavidxu
456161678Sdavidxuvoid AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(
457139257Sdavidxu    uint32_t Major, uint32_t Minor) {
458139257Sdavidxu
459139013Sdavidxu  EmitNote(ElfNote::NoteNameV2, MCConstantExpr::create(8, getContext()),
460139013Sdavidxu           ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION, [&](MCELFStreamer &OS) {
461139257Sdavidxu             OS.EmitIntValue(Major, 4);
462138224Sdavidxu             OS.EmitIntValue(Minor, 4);
463138224Sdavidxu           });
464177848Sdavidxu}
465161678Sdavidxu
466161678Sdavidxuvoid
467161678SdavidxuAMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
468161678Sdavidxu                                                       uint32_t Minor,
469161678Sdavidxu                                                       uint32_t Stepping,
470161678Sdavidxu                                                       StringRef VendorName,
471161678Sdavidxu                                                       StringRef ArchName) {
472161678Sdavidxu  uint16_t VendorNameSize = VendorName.size() + 1;
473161678Sdavidxu  uint16_t ArchNameSize = ArchName.size() + 1;
474161678Sdavidxu
475161678Sdavidxu  unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
476161678Sdavidxu    sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
477161678Sdavidxu    VendorNameSize + ArchNameSize;
478161678Sdavidxu
479161678Sdavidxu  EmitNote(ElfNote::NoteNameV2, MCConstantExpr::create(DescSZ, getContext()),
480161678Sdavidxu           ElfNote::NT_AMDGPU_HSA_ISA, [&](MCELFStreamer &OS) {
481161678Sdavidxu             OS.EmitIntValue(VendorNameSize, 2);
482161678Sdavidxu             OS.EmitIntValue(ArchNameSize, 2);
483138224Sdavidxu             OS.EmitIntValue(Major, 4);
484161678Sdavidxu             OS.EmitIntValue(Minor, 4);
485138224Sdavidxu             OS.EmitIntValue(Stepping, 4);
486161678Sdavidxu             OS.EmitBytes(VendorName);
487161678Sdavidxu             OS.EmitIntValue(0, 1); // NULL terminate VendorName
488161678Sdavidxu             OS.EmitBytes(ArchName);
489161678Sdavidxu             OS.EmitIntValue(0, 1); // NULL terminte ArchName
490161678Sdavidxu           });
491161678Sdavidxu}
492161678Sdavidxu
493161678Sdavidxuvoid
494139751SdavidxuAMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
495139751Sdavidxu
496139751Sdavidxu  MCStreamer &OS = getStreamer();
497138224Sdavidxu  OS.PushSection();
498138224Sdavidxu  OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
499161678Sdavidxu  OS.PopSection();
500161678Sdavidxu}
501161678Sdavidxu
502139013Sdavidxuvoid AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
503161678Sdavidxu                                                   unsigned Type) {
504139013Sdavidxu  MCSymbolELF *Symbol = cast<MCSymbolELF>(
505161678Sdavidxu      getStreamer().getContext().getOrCreateSymbol(SymbolName));
506139013Sdavidxu  Symbol->setType(Type);
507139013Sdavidxu}
508139013Sdavidxu
509139013Sdavidxuvoid AMDGPUTargetELFStreamer::emitAMDGPULDS(MCSymbol *Symbol, unsigned Size,
510139013Sdavidxu                                            unsigned Align) {
511139013Sdavidxu  assert(isPowerOf2_32(Align));
512161678Sdavidxu
513161678Sdavidxu  MCSymbolELF *SymbolELF = cast<MCSymbolELF>(Symbol);
514161678Sdavidxu  SymbolELF->setType(ELF::STT_OBJECT);
515161678Sdavidxu
516161678Sdavidxu  if (!SymbolELF->isBindingSet()) {
517163677Sdavidxu    SymbolELF->setBinding(ELF::STB_GLOBAL);
518163677Sdavidxu    SymbolELF->setExternal(true);
519161678Sdavidxu  }
520161678Sdavidxu
521161678Sdavidxu  if (SymbolELF->declareCommon(Size, Align, true)) {
522161678Sdavidxu    report_fatal_error("Symbol: " + Symbol->getName() +
523161678Sdavidxu                       " redeclared as different type");
524161678Sdavidxu  }
525161678Sdavidxu
526161678Sdavidxu  SymbolELF->setIndex(ELF::SHN_AMDGPU_LDS);
527161678Sdavidxu  SymbolELF->setSize(MCConstantExpr::create(Size, getContext()));
528161678Sdavidxu}
529161678Sdavidxu
530161678Sdavidxubool AMDGPUTargetELFStreamer::EmitISAVersion(StringRef IsaVersionString) {
531161678Sdavidxu  // Create two labels to mark the beginning and end of the desc field
532161678Sdavidxu  // and a MCExpr to calculate the size of the desc field.
533161678Sdavidxu  auto &Context = getContext();
534161678Sdavidxu  auto *DescBegin = Context.createTempSymbol();
535161678Sdavidxu  auto *DescEnd = Context.createTempSymbol();
536161678Sdavidxu  auto *DescSZ = MCBinaryExpr::createSub(
537161678Sdavidxu    MCSymbolRefExpr::create(DescEnd, Context),
538161678Sdavidxu    MCSymbolRefExpr::create(DescBegin, Context), Context);
539139013Sdavidxu
540139013Sdavidxu  EmitNote(ElfNote::NoteNameV2, DescSZ, ELF::NT_AMD_AMDGPU_ISA,
541161678Sdavidxu           [&](MCELFStreamer &OS) {
542139013Sdavidxu             OS.EmitLabel(DescBegin);
543139013Sdavidxu             OS.EmitBytes(IsaVersionString);
544139013Sdavidxu             OS.EmitLabel(DescEnd);
545161678Sdavidxu           });
546161678Sdavidxu  return true;
547161678Sdavidxu}
548139013Sdavidxu
549139013Sdavidxubool AMDGPUTargetELFStreamer::EmitHSAMetadata(msgpack::Document &HSAMetadataDoc,
550139013Sdavidxu                                              bool Strict) {
551161678Sdavidxu  V3::MetadataVerifier Verifier(Strict);
552139013Sdavidxu  if (!Verifier.verify(HSAMetadataDoc.getRoot()))
553139013Sdavidxu    return false;
554139013Sdavidxu
555161678Sdavidxu  std::string HSAMetadataString;
556161678Sdavidxu  HSAMetadataDoc.writeToBlob(HSAMetadataString);
557161678Sdavidxu
558139013Sdavidxu  // Create two labels to mark the beginning and end of the desc field
559163449Sdavidxu  // and a MCExpr to calculate the size of the desc field.
560112904Sjeff  auto &Context = getContext();
561143149Sdavidxu  auto *DescBegin = Context.createTempSymbol();
562163449Sdavidxu  auto *DescEnd = Context.createTempSymbol();
563163449Sdavidxu  auto *DescSZ = MCBinaryExpr::createSub(
564138224Sdavidxu      MCSymbolRefExpr::create(DescEnd, Context),
565112904Sjeff      MCSymbolRefExpr::create(DescBegin, Context), Context);
566143149Sdavidxu
567161678Sdavidxu  EmitNote(ElfNote::NoteNameV3, DescSZ, ELF::NT_AMDGPU_METADATA,
568112904Sjeff           [&](MCELFStreamer &OS) {
569161678Sdavidxu             OS.EmitLabel(DescBegin);
570112904Sjeff             OS.EmitBytes(HSAMetadataString);
571112904Sjeff             OS.EmitLabel(DescEnd);
572112904Sjeff           });
573112904Sjeff  return true;
574112904Sjeff}
575112904Sjeff
576163449Sdavidxubool AMDGPUTargetELFStreamer::EmitHSAMetadata(
577112904Sjeff    const AMDGPU::HSAMD::Metadata &HSAMetadata) {
578138224Sdavidxu  std::string HSAMetadataString;
579138224Sdavidxu  if (HSAMD::toString(HSAMetadata, HSAMetadataString))
580138224Sdavidxu    return false;
581138224Sdavidxu
582115765Sjeff  // Create two labels to mark the beginning and end of the desc field
583115765Sjeff  // and a MCExpr to calculate the size of the desc field.
584115765Sjeff  auto &Context = getContext();
585115765Sjeff  auto *DescBegin = Context.createTempSymbol();
586115765Sjeff  auto *DescEnd = Context.createTempSymbol();
587115765Sjeff  auto *DescSZ = MCBinaryExpr::createSub(
588163449Sdavidxu    MCSymbolRefExpr::create(DescEnd, Context),
589139013Sdavidxu    MCSymbolRefExpr::create(DescBegin, Context), Context);
590115765Sjeff
591138224Sdavidxu  EmitNote(ElfNote::NoteNameV2, DescSZ, ELF::NT_AMD_AMDGPU_HSA_METADATA,
592138224Sdavidxu           [&](MCELFStreamer &OS) {
593138224Sdavidxu             OS.EmitLabel(DescBegin);
594115765Sjeff             OS.EmitBytes(HSAMetadataString);
595115765Sjeff             OS.EmitLabel(DescEnd);
596115765Sjeff           });
597115765Sjeff  return true;
598115765Sjeff}
599115765Sjeff
600112904Sjeffbool AMDGPUTargetELFStreamer::EmitCodeEnd() {
601112904Sjeff  const uint32_t Encoded_s_code_end = 0xbf9f0000;
602138224Sdavidxu
603138224Sdavidxu  MCStreamer &OS = getStreamer();
604138224Sdavidxu  OS.PushSection();
605138224Sdavidxu  OS.EmitValueToAlignment(64, Encoded_s_code_end, 4);
606161678Sdavidxu  for (unsigned I = 0; I < 48; ++I)
607138224Sdavidxu    OS.EmitIntValue(Encoded_s_code_end, 4);
608112904Sjeff  OS.PopSection();
609161678Sdavidxu  return true;
610161678Sdavidxu}
611161678Sdavidxu
612161678Sdavidxuvoid AMDGPUTargetELFStreamer::EmitAmdhsaKernelDescriptor(
613161678Sdavidxu    const MCSubtargetInfo &STI, StringRef KernelName,
614161678Sdavidxu    const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR,
615161678Sdavidxu    uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr,
616161678Sdavidxu    bool ReserveXNACK) {
617161678Sdavidxu  auto &Streamer = getStreamer();
618161678Sdavidxu  auto &Context = Streamer.getContext();
619112904Sjeff
620112904Sjeff  MCSymbolELF *KernelCodeSymbol = cast<MCSymbolELF>(
621112904Sjeff      Context.getOrCreateSymbol(Twine(KernelName)));
622112904Sjeff  MCSymbolELF *KernelDescriptorSymbol = cast<MCSymbolELF>(
623112904Sjeff      Context.getOrCreateSymbol(Twine(KernelName) + Twine(".kd")));
624112904Sjeff
625163449Sdavidxu  // Copy kernel descriptor symbol's binding, other and visibility from the
626112904Sjeff  // kernel code symbol.
627112904Sjeff  KernelDescriptorSymbol->setBinding(KernelCodeSymbol->getBinding());
628112967Sjake  KernelDescriptorSymbol->setOther(KernelCodeSymbol->getOther());
629143149Sdavidxu  KernelDescriptorSymbol->setVisibility(KernelCodeSymbol->getVisibility());
630143149Sdavidxu  // Kernel descriptor symbol's type and size are fixed.
631143149Sdavidxu  KernelDescriptorSymbol->setType(ELF::STT_OBJECT);
632143149Sdavidxu  KernelDescriptorSymbol->setSize(
633115765Sjeff      MCConstantExpr::create(sizeof(KernelDescriptor), Context));
634112904Sjeff
635112904Sjeff  // The visibility of the kernel code symbol must be protected or less to allow
636112904Sjeff  // static relocations from the kernel descriptor to be used.
637115765Sjeff  if (KernelCodeSymbol->getVisibility() == ELF::STV_DEFAULT)
638117685Smtm    KernelCodeSymbol->setVisibility(ELF::STV_PROTECTED);
639117685Smtm
640112904Sjeff  Streamer.EmitLabel(KernelDescriptorSymbol);
641143149Sdavidxu  Streamer.EmitBytes(StringRef(
642161678Sdavidxu      (const char*)&(KernelDescriptor),
643161678Sdavidxu      offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset)));
644143149Sdavidxu  // FIXME: Remove the use of VK_AMDGPU_REL64 in the expression below. The
645143149Sdavidxu  // expression being created is:
646143149Sdavidxu  //   (start of kernel code) - (start of kernel descriptor)
647112904Sjeff  // It implies R_AMDGPU_REL64, but ends up being R_AMDGPU_ABS64.
648117743Smtm  Streamer.EmitValue(MCBinaryExpr::createSub(
649117743Smtm      MCSymbolRefExpr::create(
650112904Sjeff          KernelCodeSymbol, MCSymbolRefExpr::VK_AMDGPU_REL64, Context),
651112904Sjeff      MCSymbolRefExpr::create(
652161678Sdavidxu          KernelDescriptorSymbol, MCSymbolRefExpr::VK_None, Context),
653161678Sdavidxu      Context),
654161678Sdavidxu      sizeof(KernelDescriptor.kernel_code_entry_byte_offset));
655139013Sdavidxu  Streamer.EmitBytes(StringRef(
656163449Sdavidxu      (const char*)&(KernelDescriptor) +
657140245Sdavidxu          offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) +
658112904Sjeff          sizeof(KernelDescriptor.kernel_code_entry_byte_offset),
659140245Sdavidxu      sizeof(KernelDescriptor) -
660139013Sdavidxu          offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) -
661140245Sdavidxu          sizeof(KernelDescriptor.kernel_code_entry_byte_offset)));
662139013Sdavidxu}
663140245Sdavidxu