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