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
27namespace llvm {
28namespace AMDGPU {
29
30IsaVersion 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
50void 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
73MCSection *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
81MCSection *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
88MCSection *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
94MCSection *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
100bool isGroupSegment(const GlobalValue *GV) {
101  return GV->getType()->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
102}
103
104bool isGlobalSegment(const GlobalValue *GV) {
105  return GV->getType()->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;
106}
107
108bool isReadOnlySegment(const GlobalValue *GV) {
109  return GV->getType()->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS;
110}
111
112static unsigned getIntegerAttribute(const Function &F, const char *Name,
113                                    unsigned Default) {
114  Attribute A = F.getFnAttribute(Name);
115  unsigned Result = Default;
116
117  if (A.isStringAttribute()) {
118    StringRef Str = A.getValueAsString();
119    if (Str.getAsInteger(0, Result)) {
120      LLVMContext &Ctx = F.getContext();
121      Ctx.emitError("can't parse shader type");
122    }
123  }
124  return Result;
125}
126
127unsigned getShaderType(const Function &F) {
128  return getIntegerAttribute(F, "ShaderType", ShaderType::COMPUTE);
129}
130
131unsigned getInitialPSInputAddr(const Function &F) {
132  return getIntegerAttribute(F, "InitialPSInputAddr", 0);
133}
134
135bool isSI(const MCSubtargetInfo &STI) {
136  return STI.getFeatureBits()[AMDGPU::FeatureSouthernIslands];
137}
138
139bool isCI(const MCSubtargetInfo &STI) {
140  return STI.getFeatureBits()[AMDGPU::FeatureSeaIslands];
141}
142
143bool isVI(const MCSubtargetInfo &STI) {
144  return STI.getFeatureBits()[AMDGPU::FeatureVolcanicIslands];
145}
146
147unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI) {
148
149  switch(Reg) {
150  default: break;
151  case AMDGPU::FLAT_SCR:
152    assert(!isSI(STI));
153    return isCI(STI) ? AMDGPU::FLAT_SCR_ci : AMDGPU::FLAT_SCR_vi;
154
155  case AMDGPU::FLAT_SCR_LO:
156    assert(!isSI(STI));
157    return isCI(STI) ? AMDGPU::FLAT_SCR_LO_ci : AMDGPU::FLAT_SCR_LO_vi;
158
159  case AMDGPU::FLAT_SCR_HI:
160    assert(!isSI(STI));
161    return isCI(STI) ? AMDGPU::FLAT_SCR_HI_ci : AMDGPU::FLAT_SCR_HI_vi;
162  }
163  return Reg;
164}
165
166} // End namespace AMDGPU
167} // End namespace llvm
168