1 //===-- AMDGPUBaseInfo.cpp - AMDGPU Base encoding information--------------===// 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 #include "AMDGPUBaseInfo.h" 10 #include "AMDGPU.h" 11 #include "llvm/IR/LLVMContext.h" 12 #include "llvm/IR/Function.h" 13 #include "llvm/IR/GlobalValue.h" 14 #include "llvm/MC/MCContext.h" 15 #include "llvm/MC/MCSectionELF.h" 16 #include "llvm/MC/MCSubtargetInfo.h" 17 #include "llvm/MC/SubtargetFeature.h" 18 19 #define GET_SUBTARGETINFO_ENUM 20 #include "AMDGPUGenSubtargetInfo.inc" 21 #undef GET_SUBTARGETINFO_ENUM 22 23 #define GET_REGINFO_ENUM 24 #include "AMDGPUGenRegisterInfo.inc" 25 #undef GET_REGINFO_ENUM 26 27 namespace llvm { 28 namespace AMDGPU { 29 30 IsaVersion getIsaVersion(const FeatureBitset &Features) { 31 32 if (Features.test(FeatureISAVersion7_0_0)) 33 return {7, 0, 0}; 34 35 if (Features.test(FeatureISAVersion7_0_1)) 36 return {7, 0, 1}; 37 38 if (Features.test(FeatureISAVersion8_0_0)) 39 return {8, 0, 0}; 40 41 if (Features.test(FeatureISAVersion8_0_1)) 42 return {8, 0, 1}; 43 44 if (Features.test(FeatureISAVersion8_0_3)) 45 return {8, 0, 3}; 46 47 return {0, 0, 0}; 48 } 49 50 void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header, 51 const FeatureBitset &Features) { 52 53 IsaVersion ISA = getIsaVersion(Features); 54 55 memset(&Header, 0, sizeof(Header)); 56 57 Header.amd_kernel_code_version_major = 1; 58 Header.amd_kernel_code_version_minor = 0; 59 Header.amd_machine_kind = 1; // AMD_MACHINE_KIND_AMDGPU 60 Header.amd_machine_version_major = ISA.Major; 61 Header.amd_machine_version_minor = ISA.Minor; 62 Header.amd_machine_version_stepping = ISA.Stepping; 63 Header.kernel_code_entry_byte_offset = sizeof(Header); 64 // wavefront_size is specified as a power of 2: 2^6 = 64 threads. 65 Header.wavefront_size = 6; 66 // These alignment values are specified in powers of two, so alignment = 67 // 2^n. The minimum alignment is 2^4 = 16. 68 Header.kernarg_segment_alignment = 4; 69 Header.group_segment_alignment = 4; 70 Header.private_segment_alignment = 4; 71 } 72 73 MCSection *getHSATextSection(MCContext &Ctx) { 74 return Ctx.getELFSection(".hsatext", ELF::SHT_PROGBITS, 75 ELF::SHF_ALLOC | ELF::SHF_WRITE | 76 ELF::SHF_EXECINSTR | 77 ELF::SHF_AMDGPU_HSA_AGENT | 78 ELF::SHF_AMDGPU_HSA_CODE); 79 } 80 81 MCSection *getHSADataGlobalAgentSection(MCContext &Ctx) { 82 return Ctx.getELFSection(".hsadata_global_agent", ELF::SHT_PROGBITS, 83 ELF::SHF_ALLOC | ELF::SHF_WRITE | 84 ELF::SHF_AMDGPU_HSA_GLOBAL | 85 ELF::SHF_AMDGPU_HSA_AGENT); 86 } 87 88 MCSection *getHSADataGlobalProgramSection(MCContext &Ctx) { 89 return Ctx.getELFSection(".hsadata_global_program", ELF::SHT_PROGBITS, 90 ELF::SHF_ALLOC | ELF::SHF_WRITE | 91 ELF::SHF_AMDGPU_HSA_GLOBAL); 92 } 93 94 MCSection *getHSARodataReadonlyAgentSection(MCContext &Ctx) { 95 return Ctx.getELFSection(".hsarodata_readonly_agent", ELF::SHT_PROGBITS, 96 ELF::SHF_ALLOC | ELF::SHF_AMDGPU_HSA_READONLY | 97 ELF::SHF_AMDGPU_HSA_AGENT); 98 } 99 100 bool isGroupSegment(const GlobalValue *GV) { 101 return GV->getType()->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS; 102 } 103 104 bool isGlobalSegment(const GlobalValue *GV) { 105 return GV->getType()->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS; 106 } 107 108 bool isReadOnlySegment(const GlobalValue *GV) { 109 return GV->getType()->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS; 110 } 111 112 int getIntegerAttribute(const Function &F, StringRef Name, int Default) { 113 Attribute A = F.getFnAttribute(Name); 114 int Result = Default; 115 116 if (A.isStringAttribute()) { 117 StringRef Str = A.getValueAsString(); 118 if (Str.getAsInteger(0, Result)) { 119 LLVMContext &Ctx = F.getContext(); 120 Ctx.emitError("can't parse integer attribute " + Name); 121 } 122 } 123 124 return Result; 125 } 126 127 unsigned getMaximumWorkGroupSize(const Function &F) { 128 return getIntegerAttribute(F, "amdgpu-max-work-group-size", 256); 129 } 130 131 unsigned getInitialPSInputAddr(const Function &F) { 132 return getIntegerAttribute(F, "InitialPSInputAddr", 0); 133 } 134 135 bool isShader(CallingConv::ID cc) { 136 switch(cc) { 137 case CallingConv::AMDGPU_VS: 138 case CallingConv::AMDGPU_GS: 139 case CallingConv::AMDGPU_PS: 140 case CallingConv::AMDGPU_CS: 141 return true; 142 default: 143 return false; 144 } 145 } 146 147 bool isCompute(CallingConv::ID cc) { 148 return !isShader(cc) || cc == CallingConv::AMDGPU_CS; 149 } 150 151 bool isSI(const MCSubtargetInfo &STI) { 152 return STI.getFeatureBits()[AMDGPU::FeatureSouthernIslands]; 153 } 154 155 bool isCI(const MCSubtargetInfo &STI) { 156 return STI.getFeatureBits()[AMDGPU::FeatureSeaIslands]; 157 } 158 159 bool isVI(const MCSubtargetInfo &STI) { 160 return STI.getFeatureBits()[AMDGPU::FeatureVolcanicIslands]; 161 } 162 163 unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI) { 164 165 switch(Reg) { 166 default: break; 167 case AMDGPU::FLAT_SCR: 168 assert(!isSI(STI)); 169 return isCI(STI) ? AMDGPU::FLAT_SCR_ci : AMDGPU::FLAT_SCR_vi; 170 171 case AMDGPU::FLAT_SCR_LO: 172 assert(!isSI(STI)); 173 return isCI(STI) ? AMDGPU::FLAT_SCR_LO_ci : AMDGPU::FLAT_SCR_LO_vi; 174 175 case AMDGPU::FLAT_SCR_HI: 176 assert(!isSI(STI)); 177 return isCI(STI) ? AMDGPU::FLAT_SCR_HI_ci : AMDGPU::FLAT_SCR_HI_vi; 178 } 179 return Reg; 180 } 181 182 } // End namespace AMDGPU 183 } // End namespace llvm 184