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