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