]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/gcn/gcn.h
amdgcn: Add gfx90a support
[thirdparty/gcc.git] / gcc / config / gcn / gcn.h
1 /* Copyright (C) 2016-2022 Free Software Foundation, Inc.
2
3 This file is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License as published by the Free
5 Software Foundation; either version 3 of the License, or (at your option)
6 any later version.
7
8 This file is distributed in the hope that it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with GCC; see the file COPYING3. If not see
15 <http://www.gnu.org/licenses/>. */
16
17 #include "config/gcn/gcn-opts.h"
18
19 #define TARGET_CPU_CPP_BUILTINS() \
20 do \
21 { \
22 builtin_define ("__AMDGCN__"); \
23 if (TARGET_GCN3) \
24 builtin_define ("__GCN3__"); \
25 else if (TARGET_GCN5) \
26 builtin_define ("__GCN5__"); \
27 else if (TARGET_CDNA1) \
28 builtin_define ("__CDNA1__"); \
29 else if (TARGET_CDNA2) \
30 builtin_define ("__CDNA2__"); \
31 } \
32 while(0)
33
34 /* Support for a compile-time default architecture and tuning.
35 The rules are:
36 --with-arch is ignored if -march is specified.
37 --with-tune is ignored if -mtune is specified. */
38 #define OPTION_DEFAULT_SPECS \
39 {"arch", "%{!march=*:-march=%(VALUE)}" }, \
40 {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }
41
42 /* Default target_flags if no switches specified. */
43 #ifndef TARGET_DEFAULT
44 #define TARGET_DEFAULT 0
45 #endif
46
47 \f
48 /* Storage Layout */
49 #define BITS_BIG_ENDIAN 0
50 #define BYTES_BIG_ENDIAN 0
51 #define WORDS_BIG_ENDIAN 0
52
53 #ifdef IN_LIBGCC2
54 /* We want DImode and TImode helpers. */
55 #define UNITS_PER_WORD 8
56 #else
57 #define UNITS_PER_WORD 4
58 #endif
59
60 #define POINTER_SIZE 64
61 #define PARM_BOUNDARY 64
62 #define STACK_BOUNDARY 64
63 #define FUNCTION_BOUNDARY 32
64 #define BIGGEST_ALIGNMENT 64
65 #define EMPTY_FIELD_BOUNDARY 32
66 #define MAX_FIXED_MODE_SIZE 128
67 #define MAX_REGS_PER_ADDRESS 2
68 #define STACK_SIZE_MODE DImode
69 #define Pmode DImode
70 #define CASE_VECTOR_MODE DImode
71 #define FUNCTION_MODE QImode
72
73 #define DATA_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128)
74 #define LOCAL_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 64 ? (ALIGN) : 64)
75 #define STACK_SLOT_ALIGNMENT(TYPE,MODE,ALIGN) ((ALIGN) > 64 ? (ALIGN) : 64)
76 #define STRICT_ALIGNMENT 1
77
78 /* Type Layout: match what x86_64 does. */
79 #define INT_TYPE_SIZE 32
80 #define LONG_TYPE_SIZE 64
81 #define LONG_LONG_TYPE_SIZE 64
82 #define FLOAT_TYPE_SIZE 32
83 #define DOUBLE_TYPE_SIZE 64
84 #define LONG_DOUBLE_TYPE_SIZE 64
85 #define DEFAULT_SIGNED_CHAR 1
86 #define PCC_BITFIELD_TYPE_MATTERS 1
87
88 /* Frame Layout */
89 #define FRAME_GROWS_DOWNWARD 0
90 #define ARGS_GROW_DOWNWARD 1
91 #define STACK_POINTER_OFFSET 0
92 #define FIRST_PARM_OFFSET(FNDECL) 0
93 #define DYNAMIC_CHAIN_ADDRESS(FP) plus_constant (Pmode, (FP), -16)
94 #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNUM)
95 #define DWARF_FRAME_RETURN_COLUMN 16
96 #define STACK_DYNAMIC_OFFSET(FNDECL) (-crtl->outgoing_args_size)
97 #define ACCUMULATE_OUTGOING_ARGS 1
98 #define RETURN_ADDR_RTX(COUNT,FRAMEADDR) \
99 ((COUNT) == 0 ? get_hard_reg_initial_val (Pmode, LINK_REGNUM) : NULL_RTX)
100 \f
101 /* Register Basics */
102 #define FIRST_SGPR_REG 0
103 #define SGPR_REGNO(N) ((N)+FIRST_SGPR_REG)
104 #define LAST_SGPR_REG 101
105
106 #define FLAT_SCRATCH_REG 102
107 #define FLAT_SCRATCH_LO_REG 102
108 #define FLAT_SCRATCH_HI_REG 103
109 #define XNACK_MASK_REG 104
110 #define XNACK_MASK_LO_REG 104
111 #define XNACK_MASK_HI_REG 105
112 #define VCC_LO_REG 106
113 #define VCC_HI_REG 107
114 #define VCCZ_REG 108
115 #define TBA_REG 109
116 #define TBA_LO_REG 109
117 #define TBA_HI_REG 110
118 #define TMA_REG 111
119 #define TMA_LO_REG 111
120 #define TMA_HI_REG 112
121 #define TTMP0_REG 113
122 #define TTMP11_REG 124
123 #define M0_REG 125
124 #define EXEC_REG 126
125 #define EXEC_LO_REG 126
126 #define EXEC_HI_REG 127
127 #define EXECZ_REG 128
128 #define SCC_REG 129
129 /* 132-159 are reserved to simplify masks. */
130 #define FIRST_VGPR_REG 160
131 #define VGPR_REGNO(N) ((N)+FIRST_VGPR_REG)
132 #define LAST_VGPR_REG 415
133
134 /* Frame Registers, and other registers */
135
136 #define HARD_FRAME_POINTER_REGNUM 14
137 #define STACK_POINTER_REGNUM 16
138 #define LINK_REGNUM 18
139 #define EXEC_SAVE_REG 20
140 #define CC_SAVE_REG 22
141 #define RETURN_VALUE_REG 24 /* Must be divisible by 4. */
142 #define STATIC_CHAIN_REGNUM 30
143 #define WORK_ITEM_ID_Z_REG 162
144 #define SOFT_ARG_REG 416
145 #define FRAME_POINTER_REGNUM 418
146 #define DWARF_LINK_REGISTER 420
147 #define FIRST_PSEUDO_REGISTER 421
148
149 #define FIRST_PARM_REG 24
150 #define NUM_PARM_REGS 6
151
152 /* There is no arg pointer. Just choose random fixed register that does
153 not intefere with anything. */
154 #define ARG_POINTER_REGNUM SOFT_ARG_REG
155
156 #define HARD_FRAME_POINTER_IS_ARG_POINTER 0
157 #define HARD_FRAME_POINTER_IS_FRAME_POINTER 0
158
159 #define SGPR_OR_VGPR_REGNO_P(N) ((N)>=FIRST_VGPR_REG && (N) <= LAST_SGPR_REG)
160 #define SGPR_REGNO_P(N) ((N) <= LAST_SGPR_REG)
161 #define VGPR_REGNO_P(N) ((N)>=FIRST_VGPR_REG && (N) <= LAST_VGPR_REG)
162 #define SSRC_REGNO_P(N) ((N) <= SCC_REG && (N) != VCCZ_REG)
163 #define SDST_REGNO_P(N) ((N) <= EXEC_HI_REG && (N) != VCCZ_REG)
164 #define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
165 #define CC_REGNO_P(X) ((X) == SCC_REG || (X) == VCC_REG)
166 #define FUNCTION_ARG_REGNO_P(N) \
167 ((N) >= FIRST_PARM_REG && (N) < (FIRST_PARM_REG + NUM_PARM_REGS))
168
169 \f
170 #define FIXED_REGISTERS { \
171 /* Scalars. */ \
172 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \
173 /* fp sp lr. */ \
174 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, \
175 /* exec_save, cc_save */ \
176 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, \
177 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
182 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
183 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
184 /* Special regs and padding. */ \
185 /* flat xnack vcc tba tma ttmp */ \
186 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
187 /* m0 exec scc */ \
188 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, \
189 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
190 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
191 /* VGRPs */ \
192 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
193 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
195 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
196 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
197 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
203 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
204 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
205 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
206 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
207 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
208 /* Other registers. */ \
209 1, 1, 1, 1, 1 \
210 }
211
212 #define CALL_USED_REGISTERS { \
213 /* Scalars. */ \
214 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
215 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, \
216 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
217 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, \
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
223 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
224 /* Special regs and padding. */ \
225 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
226 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
227 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
228 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
229 /* VGRPs */ \
230 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
231 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
233 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
234 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
235 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
236 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
237 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
238 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
239 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
246 /* Other registers. */ \
247 1, 1, 1, 1, 1 \
248 }
249
250 \f
251 #define HARD_REGNO_RENAME_OK(FROM, TO) \
252 gcn_hard_regno_rename_ok (FROM, TO)
253
254 #define HARD_REGNO_CALLER_SAVE_MODE(HARDREG, NREGS, MODE) \
255 gcn_hard_regno_caller_save_mode ((HARDREG), (NREGS), (MODE))
256
257 /* Register Classes */
258
259 enum reg_class
260 {
261 NO_REGS,
262
263 /* SCC */
264 SCC_CONDITIONAL_REG,
265
266 /* VCCZ */
267 VCCZ_CONDITIONAL_REG,
268
269 /* VCC */
270 VCC_CONDITIONAL_REG,
271
272 /* EXECZ */
273 EXECZ_CONDITIONAL_REG,
274
275 /* SCC VCCZ EXECZ */
276 ALL_CONDITIONAL_REGS,
277
278 /* EXEC */
279 EXEC_MASK_REG,
280
281 /* SGPR0-101 */
282 SGPR_REGS,
283
284 /* SGPR0-101 EXEC_LO/EXEC_HI */
285 SGPR_EXEC_REGS,
286
287 /* SGPR0-101, FLAT_SCRATCH_LO/HI, VCC LO/HI, TBA LO/HI, TMA LO/HI, TTMP0-11,
288 M0, VCCZ, SCC
289 (EXEC_LO/HI, EXECZ excluded to prevent compiler misuse.) */
290 SGPR_VOP_SRC_REGS,
291
292 /* SGPR0-101, FLAT_SCRATCH_LO/HI, XNACK_MASK_LO/HI, VCC LO/HI, TBA LO/HI
293 TMA LO/HI, TTMP0-11 */
294 SGPR_MEM_SRC_REGS,
295
296 /* SGPR0-101, FLAT_SCRATCH_LO/HI, XNACK_MASK_LO/HI, VCC LO/HI, TBA LO/HI
297 TMA LO/HI, TTMP0-11, M0, EXEC LO/HI */
298 SGPR_DST_REGS,
299
300 /* SGPR0-101, FLAT_SCRATCH_LO/HI, XNACK_MASK_LO/HI, VCC LO/HI, TBA LO/HI
301 TMA LO/HI, TTMP0-11 */
302 SGPR_SRC_REGS,
303 GENERAL_REGS,
304 VGPR_REGS,
305 ALL_GPR_REGS,
306 SRCDST_REGS,
307 AFP_REGS,
308 ALL_REGS,
309 LIM_REG_CLASSES
310 };
311
312 #define N_REG_CLASSES (int) LIM_REG_CLASSES
313
314 #define REG_CLASS_NAMES \
315 { "NO_REGS", \
316 "SCC_CONDITIONAL_REG", \
317 "VCCZ_CONDITIONAL_REG", \
318 "VCC_CONDITIONAL_REG", \
319 "EXECZ_CONDITIONAL_REG", \
320 "ALL_CONDITIONAL_REGS", \
321 "EXEC_MASK_REG", \
322 "SGPR_REGS", \
323 "SGPR_EXEC_REGS", \
324 "SGPR_VOP3A_SRC_REGS", \
325 "SGPR_MEM_SRC_REGS", \
326 "SGPR_DST_REGS", \
327 "SGPR_SRC_REGS", \
328 "GENERAL_REGS", \
329 "VGPR_REGS", \
330 "ALL_GPR_REGS", \
331 "SRCDST_REGS", \
332 "AFP_REGS", \
333 "ALL_REGS" \
334 }
335
336 #define NAMED_REG_MASK(N) (1<<((N)-3*32))
337 #define NAMED_REG_MASK2(N) (1<<((N)-4*32))
338
339 #define REG_CLASS_CONTENTS { \
340 /* NO_REGS. */ \
341 {0, 0, 0, 0, \
342 0, 0, 0, 0, \
343 0, 0, 0, 0, 0, 0}, \
344 /* SCC_CONDITIONAL_REG. */ \
345 {0, 0, 0, 0, \
346 NAMED_REG_MASK2 (SCC_REG), 0, 0, 0, \
347 0, 0, 0, 0, 0}, \
348 /* VCCZ_CONDITIONAL_REG. */ \
349 {0, 0, 0, NAMED_REG_MASK (VCCZ_REG), \
350 0, 0, 0, 0, \
351 0, 0, 0, 0, 0, 0}, \
352 /* VCC_CONDITIONAL_REG. */ \
353 {0, 0, 0, NAMED_REG_MASK (VCC_LO_REG)|NAMED_REG_MASK (VCC_HI_REG), \
354 0, 0, 0, 0, \
355 0, 0, 0, 0, 0, 0}, \
356 /* EXECZ_CONDITIONAL_REG. */ \
357 {0, 0, 0, 0, \
358 NAMED_REG_MASK2 (EXECZ_REG), 0, 0, 0, \
359 0, 0, 0, 0, 0}, \
360 /* ALL_CONDITIONAL_REGS. */ \
361 {0, 0, 0, NAMED_REG_MASK (VCCZ_REG), \
362 NAMED_REG_MASK2 (EXECZ_REG) | NAMED_REG_MASK2 (SCC_REG), 0, 0, 0, \
363 0, 0, 0, 0, 0, 0}, \
364 /* EXEC_MASK_REG. */ \
365 {0, 0, 0, NAMED_REG_MASK (EXEC_LO_REG) | NAMED_REG_MASK (EXEC_HI_REG), \
366 0, 0, 0, 0, \
367 0, 0, 0, 0, 0, 0}, \
368 /* SGPR_REGS. */ \
369 {0xffffffff, 0xffffffff, 0xffffffff, 0xf1, \
370 0, 0, 0, 0, \
371 0, 0, 0, 0, 0, 0}, \
372 /* SGPR_EXEC_REGS. */ \
373 {0xffffffff, 0xffffffff, 0xffffffff, \
374 0xf1 | NAMED_REG_MASK (EXEC_LO_REG) | NAMED_REG_MASK (EXEC_HI_REG), \
375 0, 0, 0, 0, \
376 0, 0, 0, 0, 0, 0}, \
377 /* SGPR_VOP_SRC_REGS. */ \
378 {0xffffffff, 0xffffffff, 0xffffffff, \
379 0xffffffff \
380 -NAMED_REG_MASK (EXEC_LO_REG) \
381 -NAMED_REG_MASK (EXEC_HI_REG), \
382 NAMED_REG_MASK2 (SCC_REG), 0, 0, 0, \
383 0, 0, 0, 0, 0, 0}, \
384 /* SGPR_MEM_SRC_REGS. */ \
385 {0xffffffff, 0xffffffff, 0xffffffff, \
386 0xffffffff-NAMED_REG_MASK (VCCZ_REG)-NAMED_REG_MASK (M0_REG) \
387 -NAMED_REG_MASK (EXEC_LO_REG)-NAMED_REG_MASK (EXEC_HI_REG), \
388 0, 0, 0, 0, \
389 0, 0, 0, 0, 0, 0}, \
390 /* SGPR_DST_REGS. */ \
391 {0xffffffff, 0xffffffff, 0xffffffff, \
392 0xffffffff-NAMED_REG_MASK (VCCZ_REG), \
393 0, 0, 0, 0, \
394 0, 0, 0, 0, 0, 0}, \
395 /* SGPR_SRC_REGS. */ \
396 {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, \
397 NAMED_REG_MASK2 (EXECZ_REG) | NAMED_REG_MASK2 (SCC_REG), 0, 0, 0, \
398 0, 0, 0, 0, 0, 0}, \
399 /* GENERAL_REGS. */ \
400 {0xffffffff, 0xffffffff, 0xffffffff, 0xf1, \
401 0, 0, 0, 0, \
402 0, 0, 0, 0, 0, 0}, \
403 /* VGPR_REGS. */ \
404 {0, 0, 0, 0, \
405 0, 0xffffffff, 0xffffffff, 0xffffffff, \
406 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0}, \
407 /* ALL_GPR_REGS. */ \
408 {0xffffffff, 0xffffffff, 0xffffffff, 0xf1, \
409 0, 0xffffffff, 0xffffffff, 0xffffffff, \
410 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0}, \
411 /* SRCDST_REGS. */ \
412 {0xffffffff, 0xffffffff, 0xffffffff, \
413 0xffffffff-NAMED_REG_MASK (VCCZ_REG), \
414 0, 0xffffffff, 0xffffffff, 0xffffffff, \
415 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0}, \
416 /* AFP_REGS. */ \
417 {0, 0, 0, 0, \
418 0, 0, 0, 0, \
419 0, 0, 0, 0, 0, 0xf}, \
420 /* ALL_REGS. */ \
421 {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, \
422 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, \
423 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0 }}
424
425 #define REGNO_REG_CLASS(REGNO) gcn_regno_reg_class (REGNO)
426 #define MODE_CODE_BASE_REG_CLASS(MODE, AS, OUTER, INDEX) \
427 gcn_mode_code_base_reg_class (MODE, AS, OUTER, INDEX)
428 #define REGNO_MODE_CODE_OK_FOR_BASE_P(NUM, MODE, AS, OUTER, INDEX) \
429 gcn_regno_mode_code_ok_for_base_p (NUM, MODE, AS, OUTER, INDEX)
430 #define INDEX_REG_CLASS VGPR_REGS
431 #define REGNO_OK_FOR_INDEX_P(regno) regno_ok_for_index_p (regno)
432
433 \f
434 /* Address spaces. */
435 enum gcn_address_spaces
436 {
437 ADDR_SPACE_DEFAULT = 0,
438 ADDR_SPACE_FLAT,
439 ADDR_SPACE_SCALAR_FLAT,
440 ADDR_SPACE_FLAT_SCRATCH,
441 ADDR_SPACE_LDS,
442 ADDR_SPACE_GDS,
443 ADDR_SPACE_SCRATCH,
444 ADDR_SPACE_GLOBAL
445 };
446 #define REGISTER_TARGET_PRAGMAS() do { \
447 c_register_addr_space ("__flat", ADDR_SPACE_FLAT); \
448 c_register_addr_space ("__flat_scratch", ADDR_SPACE_FLAT_SCRATCH); \
449 c_register_addr_space ("__scalar_flat", ADDR_SPACE_SCALAR_FLAT); \
450 c_register_addr_space ("__lds", ADDR_SPACE_LDS); \
451 c_register_addr_space ("__gds", ADDR_SPACE_GDS); \
452 c_register_addr_space ("__global", ADDR_SPACE_GLOBAL); \
453 } while (0);
454
455 #define STACK_ADDR_SPACE \
456 (TARGET_GCN5_PLUS ? ADDR_SPACE_GLOBAL : ADDR_SPACE_FLAT)
457 #define DEFAULT_ADDR_SPACE \
458 ((cfun && cfun->machine && !cfun->machine->use_flat_addressing) \
459 ? ADDR_SPACE_GLOBAL : ADDR_SPACE_FLAT)
460 #define AS_SCALAR_FLAT_P(AS) ((AS) == ADDR_SPACE_SCALAR_FLAT)
461 #define AS_FLAT_SCRATCH_P(AS) ((AS) == ADDR_SPACE_FLAT_SCRATCH)
462 #define AS_FLAT_P(AS) ((AS) == ADDR_SPACE_FLAT \
463 || ((AS) == ADDR_SPACE_DEFAULT \
464 && DEFAULT_ADDR_SPACE == ADDR_SPACE_FLAT))
465 #define AS_LDS_P(AS) ((AS) == ADDR_SPACE_LDS)
466 #define AS_GDS_P(AS) ((AS) == ADDR_SPACE_GDS)
467 #define AS_SCRATCH_P(AS) ((AS) == ADDR_SPACE_SCRATCH)
468 #define AS_GLOBAL_P(AS) ((AS) == ADDR_SPACE_GLOBAL \
469 || ((AS) == ADDR_SPACE_DEFAULT \
470 && DEFAULT_ADDR_SPACE == ADDR_SPACE_GLOBAL))
471 #define AS_ANY_FLAT_P(AS) (AS_FLAT_SCRATCH_P (AS) || AS_FLAT_P (AS))
472 #define AS_ANY_DS_P(AS) (AS_LDS_P (AS) || AS_GDS_P (AS))
473
474 \f
475 /* Instruction Output */
476 #define REGISTER_NAMES \
477 {"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", \
478 "s11", "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", \
479 "s21", "s22", "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", \
480 "s31", "s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39", "s40", \
481 "s41", "s42", "s43", "s44", "s45", "s46", "s47", "s48", "s49", "s50", \
482 "s51", "s52", "s53", "s54", "s55", "s56", "s57", "s58", "s59", "s60", \
483 "s61", "s62", "s63", "s64", "s65", "s66", "s67", "s68", "s69", "s70", \
484 "s71", "s72", "s73", "s74", "s75", "s76", "s77", "s78", "s79", "s80", \
485 "s81", "s82", "s83", "s84", "s85", "s86", "s87", "s88", "s89", "s90", \
486 "s91", "s92", "s93", "s94", "s95", "s96", "s97", "s98", "s99", \
487 "s100", "s101", \
488 "flat_scratch_lo", "flat_scratch_hi", "xnack_mask_lo", "xnack_mask_hi", \
489 "vcc_lo", "vcc_hi", "vccz", "tba_lo", "tba_hi", "tma_lo", "tma_hi", \
490 "ttmp0", "ttmp1", "ttmp2", "ttmp3", "ttmp4", "ttmp5", "ttmp6", "ttmp7", \
491 "ttmp8", "ttmp9", "ttmp10", "ttmp11", "m0", "exec_lo", "exec_hi", \
492 "execz", "scc", \
493 "res130", "res131", "res132", "res133", "res134", "res135", "res136", \
494 "res137", "res138", "res139", "res140", "res141", "res142", "res143", \
495 "res144", "res145", "res146", "res147", "res148", "res149", "res150", \
496 "res151", "res152", "res153", "res154", "res155", "res156", "res157", \
497 "res158", "res159", \
498 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", \
499 "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", \
500 "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", \
501 "v31", "v32", "v33", "v34", "v35", "v36", "v37", "v38", "v39", "v40", \
502 "v41", "v42", "v43", "v44", "v45", "v46", "v47", "v48", "v49", "v50", \
503 "v51", "v52", "v53", "v54", "v55", "v56", "v57", "v58", "v59", "v60", \
504 "v61", "v62", "v63", "v64", "v65", "v66", "v67", "v68", "v69", "v70", \
505 "v71", "v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79", "v80", \
506 "v81", "v82", "v83", "v84", "v85", "v86", "v87", "v88", "v89", "v90", \
507 "v91", "v92", "v93", "v94", "v95", "v96", "v97", "v98", "v99", "v100", \
508 "v101", "v102", "v103", "v104", "v105", "v106", "v107", "v108", "v109", \
509 "v110", "v111", "v112", "v113", "v114", "v115", "v116", "v117", "v118", \
510 "v119", "v120", "v121", "v122", "v123", "v124", "v125", "v126", "v127", \
511 "v128", "v129", "v130", "v131", "v132", "v133", "v134", "v135", "v136", \
512 "v137", "v138", "v139", "v140", "v141", "v142", "v143", "v144", "v145", \
513 "v146", "v147", "v148", "v149", "v150", "v151", "v152", "v153", "v154", \
514 "v155", "v156", "v157", "v158", "v159", "v160", "v161", "v162", "v163", \
515 "v164", "v165", "v166", "v167", "v168", "v169", "v170", "v171", "v172", \
516 "v173", "v174", "v175", "v176", "v177", "v178", "v179", "v180", "v181", \
517 "v182", "v183", "v184", "v185", "v186", "v187", "v188", "v189", "v190", \
518 "v191", "v192", "v193", "v194", "v195", "v196", "v197", "v198", "v199", \
519 "v200", "v201", "v202", "v203", "v204", "v205", "v206", "v207", "v208", \
520 "v209", "v210", "v211", "v212", "v213", "v214", "v215", "v216", "v217", \
521 "v218", "v219", "v220", "v221", "v222", "v223", "v224", "v225", "v226", \
522 "v227", "v228", "v229", "v230", "v231", "v232", "v233", "v234", "v235", \
523 "v236", "v237", "v238", "v239", "v240", "v241", "v242", "v243", "v244", \
524 "v245", "v246", "v247", "v248", "v249", "v250", "v251", "v252", "v253", \
525 "v254", "v255", \
526 "?ap0", "?ap1", "?fp0", "?fp1", "?dwlr" }
527
528 #define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE, X, CODE)
529 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
530 #define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '^')
531
532 \f
533 /* Register Arguments */
534
535 #ifndef USED_FOR_TARGET
536
537 #define GCN_KERNEL_ARG_TYPES 16
538 struct GTY(()) gcn_kernel_args
539 {
540 long requested;
541 int reg[GCN_KERNEL_ARG_TYPES];
542 int order[GCN_KERNEL_ARG_TYPES];
543 int nargs, nsgprs;
544 };
545
546 typedef struct gcn_args
547 {
548 /* True if this isn't a kernel (HSA runtime entrypoint). */
549 bool normal_function;
550 tree fntype;
551 struct gcn_kernel_args args;
552 int num;
553 int offset;
554 int alignment;
555 } CUMULATIVE_ARGS;
556 #endif
557
558 #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \
559 gcn_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL), \
560 (N_NAMED_ARGS) != -1)
561
562 \f
563 #ifndef USED_FOR_TARGET
564
565 #include "hash-table.h"
566 #include "hash-map.h"
567 #include "vec.h"
568
569 struct GTY(()) machine_function
570 {
571 struct gcn_kernel_args args;
572 int kernarg_segment_alignment;
573 int kernarg_segment_byte_size;
574 /* Frame layout info for normal functions. */
575 bool normal_function;
576 bool need_frame_pointer;
577 bool lr_needs_saving;
578 HOST_WIDE_INT outgoing_args_size;
579 HOST_WIDE_INT pretend_size;
580 HOST_WIDE_INT local_vars;
581 HOST_WIDE_INT callee_saves;
582
583 unsigned HOST_WIDE_INT reduction_base;
584 unsigned HOST_WIDE_INT reduction_limit;
585
586 bool use_flat_addressing;
587 };
588 #endif
589
590 \f
591 /* Codes for all the GCN builtins. */
592
593 enum gcn_builtin_codes
594 {
595 #define DEF_BUILTIN(fcode, icode, name, type, params, expander) \
596 GCN_BUILTIN_ ## fcode,
597 #define DEF_BUILTIN_BINOP_INT_FP(fcode, ic, name) \
598 GCN_BUILTIN_ ## fcode ## _V64SI, \
599 GCN_BUILTIN_ ## fcode ## _V64SI_unspec,
600 #include "gcn-builtins.def"
601 #undef DEF_BUILTIN
602 #undef DEF_BUILTIN_BINOP_INT_FP
603 GCN_BUILTIN_MAX
604 };
605
606 \f
607 /* Misc */
608
609 /* We can load/store 128-bit quantities, but having this larger than
610 MAX_FIXED_MODE_SIZE (which we want to be 64 bits) causes problems. */
611 #define MOVE_MAX 8
612
613 #define AVOID_CCMODE_COPIES 1
614 #define SLOW_BYTE_ACCESS 0
615 #define WORD_REGISTER_OPERATIONS 1
616
617 /* Flag values are either BImode or DImode, but either way the compiler
618 should assume that all the bits are live. */
619 #define STORE_FLAG_VALUE -1
620
621 /* Definitions for register eliminations.
622
623 This is an array of structures. Each structure initializes one pair
624 of eliminable registers. The "from" register number is given first,
625 followed by "to". Eliminations of the same "from" register are listed
626 in order of preference. */
627
628 #define ELIMINABLE_REGS \
629 {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
630 { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
631 { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
632 { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
633
634 /* Define the offset between two registers, one to be eliminated, and the
635 other its replacement, at the start of a routine. */
636
637 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
638 ((OFFSET) = gcn_initial_elimination_offset ((FROM), (TO)))
639
640
641 /* Define this macro if it is advisable to hold scalars in registers
642 in a wider mode than that declared by the program. In such cases,
643 the value is constrained to be within the bounds of the declared
644 type, but kept valid in the wider mode. The signedness of the
645 extension may differ from that of the type. */
646
647 #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
648 if (GET_MODE_CLASS (MODE) == MODE_INT \
649 && (TYPE == NULL || TREE_CODE (TYPE) != VECTOR_TYPE) \
650 && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
651 { \
652 (MODE) = SImode; \
653 }
654
655 /* This needs to match gcn_function_value. */
656 #define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, SGPR_REGNO (RETURN_VALUE_REG))
657
658 /* The s_ff0 and s_flbit instructions return -1 if no input bits are set. */
659 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2)
660 #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2)
661
662 \f
663 /* Costs. */
664
665 /* Branches are to be dicouraged when theres an alternative.
666 FIXME: This number is plucked from the air. */
667 #define BRANCH_COST(SPEED_P, PREDICABLE_P) 10
668
669 \f
670 /* Profiling */
671 #define FUNCTION_PROFILER(FILE, LABELNO)
672 #define NO_PROFILE_COUNTERS 1
673 #define PROFILE_BEFORE_PROLOGUE 0
674
675 /* Trampolines */
676 #define TRAMPOLINE_SIZE 36
677 #define TRAMPOLINE_ALIGNMENT 64