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 std::pair<int, int> getIntegerPairAttribute(const Function &F, 128 StringRef Name, 129 std::pair<int, int> Default, 130 bool OnlyFirstRequired) { 131 Attribute A = F.getFnAttribute(Name); 132 if (!A.isStringAttribute()) 133 return Default; 134 135 LLVMContext &Ctx = F.getContext(); 136 std::pair<int, int> Ints = Default; 137 std::pair<StringRef, StringRef> Strs = A.getValueAsString().split(','); 138 if (Strs.first.trim().getAsInteger(0, Ints.first)) { 139 Ctx.emitError("can't parse first integer attribute " + Name); 140 return Default; 141 } 142 if (Strs.second.trim().getAsInteger(0, Ints.second)) { 143 if (!OnlyFirstRequired || Strs.second.trim().size()) { 144 Ctx.emitError("can't parse second integer attribute " + Name); 145 return Default; 146 } 147 } 148 149 return Ints; 150 } 151 152 unsigned getInitialPSInputAddr(const Function &F) { 153 return getIntegerAttribute(F, "InitialPSInputAddr", 0); 154 } 155 156 bool isShader(CallingConv::ID cc) { 157 switch(cc) { 158 case CallingConv::AMDGPU_VS: 159 case CallingConv::AMDGPU_GS: 160 case CallingConv::AMDGPU_PS: 161 case CallingConv::AMDGPU_CS: 162 return true; 163 default: 164 return false; 165 } 166 } 167 168 bool isCompute(CallingConv::ID cc) { 169 return !isShader(cc) || cc == CallingConv::AMDGPU_CS; 170 } 171 172 bool isSI(const MCSubtargetInfo &STI) { 173 return STI.getFeatureBits()[AMDGPU::FeatureSouthernIslands]; 174 } 175 176 bool isCI(const MCSubtargetInfo &STI) { 177 return STI.getFeatureBits()[AMDGPU::FeatureSeaIslands]; 178 } 179 180 bool isVI(const MCSubtargetInfo &STI) { 181 return STI.getFeatureBits()[AMDGPU::FeatureVolcanicIslands]; 182 } 183 184 unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI) { 185 186 switch(Reg) { 187 default: break; 188 case AMDGPU::FLAT_SCR: 189 assert(!isSI(STI)); 190 return isCI(STI) ? AMDGPU::FLAT_SCR_ci : AMDGPU::FLAT_SCR_vi; 191 192 case AMDGPU::FLAT_SCR_LO: 193 assert(!isSI(STI)); 194 return isCI(STI) ? AMDGPU::FLAT_SCR_LO_ci : AMDGPU::FLAT_SCR_LO_vi; 195 196 case AMDGPU::FLAT_SCR_HI: 197 assert(!isSI(STI)); 198 return isCI(STI) ? AMDGPU::FLAT_SCR_HI_ci : AMDGPU::FLAT_SCR_HI_vi; 199 } 200 return Reg; 201 } 202 203 } // End namespace AMDGPU 204 } // End namespace llvm 205