/* Copyright (C) 2016-2020 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This file is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
. */
#include "config/gcn/gcn-opts.h"
#define TARGET_CPU_CPP_BUILTINS() \
do \
{ \
builtin_define ("__AMDGCN__"); \
if (TARGET_GCN3) \
builtin_define ("__GCN3__"); \
else if (TARGET_GCN5) \
builtin_define ("__GCN5__"); \
} \
while(0)
/* Support for a compile-time default architecture and tuning.
The rules are:
--with-arch is ignored if -march is specified.
--with-tune is ignored if -mtune is specified. */
#define OPTION_DEFAULT_SPECS \
{"arch", "%{!march=*:-march=%(VALUE)}" }, \
{"tune", "%{!mtune=*:-mtune=%(VALUE)}" }
/* Default target_flags if no switches specified. */
#ifndef TARGET_DEFAULT
#define TARGET_DEFAULT 0
#endif
/* Storage Layout */
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0
#define WORDS_BIG_ENDIAN 0
#define BITS_PER_WORD 32
#define UNITS_PER_WORD (BITS_PER_WORD/BITS_PER_UNIT)
#define LIBGCC2_UNITS_PER_WORD 4
#define POINTER_SIZE 64
#define PARM_BOUNDARY 64
#define STACK_BOUNDARY 64
#define FUNCTION_BOUNDARY 32
#define BIGGEST_ALIGNMENT 64
#define EMPTY_FIELD_BOUNDARY 32
#define MAX_FIXED_MODE_SIZE 64
#define MAX_REGS_PER_ADDRESS 2
#define STACK_SIZE_MODE DImode
#define Pmode DImode
#define CASE_VECTOR_MODE DImode
#define FUNCTION_MODE QImode
#define DATA_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128)
#define LOCAL_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 64 ? (ALIGN) : 64)
#define STACK_SLOT_ALIGNMENT(TYPE,MODE,ALIGN) ((ALIGN) > 64 ? (ALIGN) : 64)
#define STRICT_ALIGNMENT 1
/* Type Layout: match what x86_64 does. */
#define INT_TYPE_SIZE 32
#define LONG_TYPE_SIZE 64
#define LONG_LONG_TYPE_SIZE 64
#define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 64
#define LONG_DOUBLE_TYPE_SIZE 64
#define DEFAULT_SIGNED_CHAR 1
#define PCC_BITFIELD_TYPE_MATTERS 1
/* Frame Layout */
#define FRAME_GROWS_DOWNWARD 0
#define ARGS_GROW_DOWNWARD 1
#define STACK_POINTER_OFFSET 0
#define FIRST_PARM_OFFSET(FNDECL) 0
#define DYNAMIC_CHAIN_ADDRESS(FP) plus_constant (Pmode, (FP), -16)
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNUM)
#define STACK_DYNAMIC_OFFSET(FNDECL) (-crtl->outgoing_args_size)
#define ACCUMULATE_OUTGOING_ARGS 1
#define RETURN_ADDR_RTX(COUNT,FRAMEADDR) \
((COUNT) == 0 ? get_hard_reg_initial_val (Pmode, LINK_REGNUM) : NULL_RTX)
/* Register Basics */
#define FIRST_SGPR_REG 0
#define SGPR_REGNO(N) ((N)+FIRST_SGPR_REG)
#define LAST_SGPR_REG 101
#define FLAT_SCRATCH_REG 102
#define FLAT_SCRATCH_LO_REG 102
#define FLAT_SCRATCH_HI_REG 103
#define XNACK_MASK_REG 104
#define XNACK_MASK_LO_REG 104
#define XNACK_MASK_HI_REG 105
#define VCC_LO_REG 106
#define VCC_HI_REG 107
#define VCCZ_REG 108
#define TBA_REG 109
#define TBA_LO_REG 109
#define TBA_HI_REG 110
#define TMA_REG 111
#define TMA_LO_REG 111
#define TMA_HI_REG 112
#define TTMP0_REG 113
#define TTMP11_REG 124
#define M0_REG 125
#define EXEC_REG 126
#define EXEC_LO_REG 126
#define EXEC_HI_REG 127
#define EXECZ_REG 128
#define SCC_REG 129
/* 132-159 are reserved to simplify masks. */
#define FIRST_VGPR_REG 160
#define VGPR_REGNO(N) ((N)+FIRST_VGPR_REG)
#define LAST_VGPR_REG 415
/* Frame Registers, and other registers */
#define HARD_FRAME_POINTER_REGNUM 14
#define STACK_POINTER_REGNUM 16
#define LINK_REGNUM 18
#define EXEC_SAVE_REG 20
#define CC_SAVE_REG 22
#define RETURN_VALUE_REG 24 /* Must be divisible by 4. */
#define STATIC_CHAIN_REGNUM 30
#define WORK_ITEM_ID_Z_REG 162
#define SOFT_ARG_REG 416
#define FRAME_POINTER_REGNUM 418
#define FIRST_PSEUDO_REGISTER 420
#define FIRST_PARM_REG 24
#define NUM_PARM_REGS 6
/* There is no arg pointer. Just choose random fixed register that does
not intefere with anything. */
#define ARG_POINTER_REGNUM SOFT_ARG_REG
#define HARD_FRAME_POINTER_IS_ARG_POINTER 0
#define HARD_FRAME_POINTER_IS_FRAME_POINTER 0
#define SGPR_OR_VGPR_REGNO_P(N) ((N)>=FIRST_VGPR_REG && (N) <= LAST_SGPR_REG)
#define SGPR_REGNO_P(N) ((N) <= LAST_SGPR_REG)
#define VGPR_REGNO_P(N) ((N)>=FIRST_VGPR_REG && (N) <= LAST_VGPR_REG)
#define SSRC_REGNO_P(N) ((N) <= SCC_REG && (N) != VCCZ_REG)
#define SDST_REGNO_P(N) ((N) <= EXEC_HI_REG && (N) != VCCZ_REG)
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
#define CC_REGNO_P(X) ((X) == SCC_REG || (X) == VCC_REG)
#define FUNCTION_ARG_REGNO_P(N) \
((N) >= FIRST_PARM_REG && (N) < (FIRST_PARM_REG + NUM_PARM_REGS))
#define FIXED_REGISTERS { \
/* Scalars. */ \
1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \
/* fp sp lr. */ \
1, 1, 0, 0, 0, 0, 1, 1, 0, 0, \
/* exec_save, cc_save */ \
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
/* Special regs and padding. */ \
/* flat xnack vcc tba tma ttmp */ \
1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
/* m0 exec scc */ \
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
/* VGRPs */ \
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* Other registers. */ \
1, 1, 1, 1 \
}
#define CALL_USED_REGISTERS { \
/* Scalars. */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 0, 0, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
/* Special regs and padding. */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
/* VGRPs */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* Other registers. */ \
1, 1, 1, 1 \
}
#define HARD_REGNO_RENAME_OK(FROM, TO) \
gcn_hard_regno_rename_ok (FROM, TO)
#define HARD_REGNO_CALLER_SAVE_MODE(HARDREG, NREGS, MODE) \
gcn_hard_regno_caller_save_mode ((HARDREG), (NREGS), (MODE))
/* Register Classes */
enum reg_class
{
NO_REGS,
/* SCC */
SCC_CONDITIONAL_REG,
/* VCCZ */
VCCZ_CONDITIONAL_REG,
/* VCC */
VCC_CONDITIONAL_REG,
/* EXECZ */
EXECZ_CONDITIONAL_REG,
/* SCC VCCZ EXECZ */
ALL_CONDITIONAL_REGS,
/* EXEC */
EXEC_MASK_REG,
/* SGPR0-101 */
SGPR_REGS,
/* SGPR0-101 EXEC_LO/EXEC_HI */
SGPR_EXEC_REGS,
/* SGPR0-101, FLAT_SCRATCH_LO/HI, VCC LO/HI, TBA LO/HI, TMA LO/HI, TTMP0-11,
M0, VCCZ, SCC
(EXEC_LO/HI, EXECZ excluded to prevent compiler misuse.) */
SGPR_VOP_SRC_REGS,
/* SGPR0-101, FLAT_SCRATCH_LO/HI, XNACK_MASK_LO/HI, VCC LO/HI, TBA LO/HI
TMA LO/HI, TTMP0-11 */
SGPR_MEM_SRC_REGS,
/* SGPR0-101, FLAT_SCRATCH_LO/HI, XNACK_MASK_LO/HI, VCC LO/HI, TBA LO/HI
TMA LO/HI, TTMP0-11, M0, EXEC LO/HI */
SGPR_DST_REGS,
/* SGPR0-101, FLAT_SCRATCH_LO/HI, XNACK_MASK_LO/HI, VCC LO/HI, TBA LO/HI
TMA LO/HI, TTMP0-11 */
SGPR_SRC_REGS,
GENERAL_REGS,
VGPR_REGS,
ALL_GPR_REGS,
SRCDST_REGS,
AFP_REGS,
ALL_REGS,
LIM_REG_CLASSES
};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
#define REG_CLASS_NAMES \
{ "NO_REGS", \
"SCC_CONDITIONAL_REG", \
"VCCZ_CONDITIONAL_REG", \
"VCC_CONDITIONAL_REG", \
"EXECZ_CONDITIONAL_REG", \
"ALL_CONDITIONAL_REGS", \
"EXEC_MASK_REG", \
"SGPR_REGS", \
"SGPR_EXEC_REGS", \
"SGPR_VOP3A_SRC_REGS", \
"SGPR_MEM_SRC_REGS", \
"SGPR_DST_REGS", \
"SGPR_SRC_REGS", \
"GENERAL_REGS", \
"VGPR_REGS", \
"ALL_GPR_REGS", \
"SRCDST_REGS", \
"AFP_REGS", \
"ALL_REGS" \
}
#define NAMED_REG_MASK(N) (1<<((N)-3*32))
#define NAMED_REG_MASK2(N) (1<<((N)-4*32))
#define REG_CLASS_CONTENTS { \
/* NO_REGS. */ \
{0, 0, 0, 0, \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* SCC_CONDITIONAL_REG. */ \
{0, 0, 0, 0, \
NAMED_REG_MASK2 (SCC_REG), 0, 0, 0, \
0, 0, 0, 0, 0}, \
/* VCCZ_CONDITIONAL_REG. */ \
{0, 0, 0, NAMED_REG_MASK (VCCZ_REG), \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* VCC_CONDITIONAL_REG. */ \
{0, 0, 0, NAMED_REG_MASK (VCC_LO_REG)|NAMED_REG_MASK (VCC_HI_REG), \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* EXECZ_CONDITIONAL_REG. */ \
{0, 0, 0, 0, \
NAMED_REG_MASK2 (EXECZ_REG), 0, 0, 0, \
0, 0, 0, 0, 0}, \
/* ALL_CONDITIONAL_REGS. */ \
{0, 0, 0, NAMED_REG_MASK (VCCZ_REG), \
NAMED_REG_MASK2 (EXECZ_REG) | NAMED_REG_MASK2 (SCC_REG), 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* EXEC_MASK_REG. */ \
{0, 0, 0, NAMED_REG_MASK (EXEC_LO_REG) | NAMED_REG_MASK (EXEC_HI_REG), \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* SGPR_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, 0xf1, \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* SGPR_EXEC_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, \
0xf1 | NAMED_REG_MASK (EXEC_LO_REG) | NAMED_REG_MASK (EXEC_HI_REG), \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* SGPR_VOP_SRC_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, \
0xffffffff \
-NAMED_REG_MASK (EXEC_LO_REG) \
-NAMED_REG_MASK (EXEC_HI_REG), \
NAMED_REG_MASK2 (SCC_REG), 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* SGPR_MEM_SRC_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, \
0xffffffff-NAMED_REG_MASK (VCCZ_REG)-NAMED_REG_MASK (M0_REG) \
-NAMED_REG_MASK (EXEC_LO_REG)-NAMED_REG_MASK (EXEC_HI_REG), \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* SGPR_DST_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, \
0xffffffff-NAMED_REG_MASK (VCCZ_REG), \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* SGPR_SRC_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, \
NAMED_REG_MASK2 (EXECZ_REG) | NAMED_REG_MASK2 (SCC_REG), 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* GENERAL_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, 0xf1, \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0}, \
/* VGPR_REGS. */ \
{0, 0, 0, 0, \
0, 0xffffffff, 0xffffffff, 0xffffffff, \
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0}, \
/* ALL_GPR_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, 0xf1, \
0, 0xffffffff, 0xffffffff, 0xffffffff, \
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0}, \
/* SRCDST_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, \
0xffffffff-NAMED_REG_MASK (VCCZ_REG), \
0, 0xffffffff, 0xffffffff, 0xffffffff, \
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0}, \
/* AFP_REGS. */ \
{0, 0, 0, 0, \
0, 0, 0, 0, \
0, 0, 0, 0, 0, 0xf}, \
/* ALL_REGS. */ \
{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, \
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, \
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0 }}
#define REGNO_REG_CLASS(REGNO) gcn_regno_reg_class (REGNO)
#define MODE_CODE_BASE_REG_CLASS(MODE, AS, OUTER, INDEX) \
gcn_mode_code_base_reg_class (MODE, AS, OUTER, INDEX)
#define REGNO_MODE_CODE_OK_FOR_BASE_P(NUM, MODE, AS, OUTER, INDEX) \
gcn_regno_mode_code_ok_for_base_p (NUM, MODE, AS, OUTER, INDEX)
#define INDEX_REG_CLASS VGPR_REGS
#define REGNO_OK_FOR_INDEX_P(regno) regno_ok_for_index_p (regno)
/* Address spaces. */
enum gcn_address_spaces
{
ADDR_SPACE_DEFAULT = 0,
ADDR_SPACE_FLAT,
ADDR_SPACE_SCALAR_FLAT,
ADDR_SPACE_FLAT_SCRATCH,
ADDR_SPACE_LDS,
ADDR_SPACE_GDS,
ADDR_SPACE_SCRATCH,
ADDR_SPACE_GLOBAL
};
#define REGISTER_TARGET_PRAGMAS() do { \
c_register_addr_space ("__flat", ADDR_SPACE_FLAT); \
c_register_addr_space ("__flat_scratch", ADDR_SPACE_FLAT_SCRATCH); \
c_register_addr_space ("__scalar_flat", ADDR_SPACE_SCALAR_FLAT); \
c_register_addr_space ("__lds", ADDR_SPACE_LDS); \
c_register_addr_space ("__gds", ADDR_SPACE_GDS); \
c_register_addr_space ("__global", ADDR_SPACE_GLOBAL); \
} while (0);
#define STACK_ADDR_SPACE \
(TARGET_GCN5_PLUS ? ADDR_SPACE_GLOBAL : ADDR_SPACE_FLAT)
#define DEFAULT_ADDR_SPACE \
((cfun && cfun->machine && !cfun->machine->use_flat_addressing) \
? ADDR_SPACE_GLOBAL : ADDR_SPACE_FLAT)
#define AS_SCALAR_FLAT_P(AS) ((AS) == ADDR_SPACE_SCALAR_FLAT)
#define AS_FLAT_SCRATCH_P(AS) ((AS) == ADDR_SPACE_FLAT_SCRATCH)
#define AS_FLAT_P(AS) ((AS) == ADDR_SPACE_FLAT \
|| ((AS) == ADDR_SPACE_DEFAULT \
&& DEFAULT_ADDR_SPACE == ADDR_SPACE_FLAT))
#define AS_LDS_P(AS) ((AS) == ADDR_SPACE_LDS)
#define AS_GDS_P(AS) ((AS) == ADDR_SPACE_GDS)
#define AS_SCRATCH_P(AS) ((AS) == ADDR_SPACE_SCRATCH)
#define AS_GLOBAL_P(AS) ((AS) == ADDR_SPACE_GLOBAL \
|| ((AS) == ADDR_SPACE_DEFAULT \
&& DEFAULT_ADDR_SPACE == ADDR_SPACE_GLOBAL))
#define AS_ANY_FLAT_P(AS) (AS_FLAT_SCRATCH_P (AS) || AS_FLAT_P (AS))
#define AS_ANY_DS_P(AS) (AS_LDS_P (AS) || AS_GDS_P (AS))
/* Instruction Output */
#define REGISTER_NAMES \
{"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", \
"s11", "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", \
"s21", "s22", "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", \
"s31", "s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39", "s40", \
"s41", "s42", "s43", "s44", "s45", "s46", "s47", "s48", "s49", "s50", \
"s51", "s52", "s53", "s54", "s55", "s56", "s57", "s58", "s59", "s60", \
"s61", "s62", "s63", "s64", "s65", "s66", "s67", "s68", "s69", "s70", \
"s71", "s72", "s73", "s74", "s75", "s76", "s77", "s78", "s79", "s80", \
"s81", "s82", "s83", "s84", "s85", "s86", "s87", "s88", "s89", "s90", \
"s91", "s92", "s93", "s94", "s95", "s96", "s97", "s98", "s99", \
"s100", "s101", \
"flat_scratch_lo", "flat_scratch_hi", "xnack_mask_lo", "xnack_mask_hi", \
"vcc_lo", "vcc_hi", "vccz", "tba_lo", "tba_hi", "tma_lo", "tma_hi", \
"ttmp0", "ttmp1", "ttmp2", "ttmp3", "ttmp4", "ttmp5", "ttmp6", "ttmp7", \
"ttmp8", "ttmp9", "ttmp10", "ttmp11", "m0", "exec_lo", "exec_hi", \
"execz", "scc", \
"res130", "res131", "res132", "res133", "res134", "res135", "res136", \
"res137", "res138", "res139", "res140", "res141", "res142", "res143", \
"res144", "res145", "res146", "res147", "res148", "res149", "res150", \
"res151", "res152", "res153", "res154", "res155", "res156", "res157", \
"res158", "res159", \
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", \
"v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", \
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", \
"v31", "v32", "v33", "v34", "v35", "v36", "v37", "v38", "v39", "v40", \
"v41", "v42", "v43", "v44", "v45", "v46", "v47", "v48", "v49", "v50", \
"v51", "v52", "v53", "v54", "v55", "v56", "v57", "v58", "v59", "v60", \
"v61", "v62", "v63", "v64", "v65", "v66", "v67", "v68", "v69", "v70", \
"v71", "v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79", "v80", \
"v81", "v82", "v83", "v84", "v85", "v86", "v87", "v88", "v89", "v90", \
"v91", "v92", "v93", "v94", "v95", "v96", "v97", "v98", "v99", "v100", \
"v101", "v102", "v103", "v104", "v105", "v106", "v107", "v108", "v109", \
"v110", "v111", "v112", "v113", "v114", "v115", "v116", "v117", "v118", \
"v119", "v120", "v121", "v122", "v123", "v124", "v125", "v126", "v127", \
"v128", "v129", "v130", "v131", "v132", "v133", "v134", "v135", "v136", \
"v137", "v138", "v139", "v140", "v141", "v142", "v143", "v144", "v145", \
"v146", "v147", "v148", "v149", "v150", "v151", "v152", "v153", "v154", \
"v155", "v156", "v157", "v158", "v159", "v160", "v161", "v162", "v163", \
"v164", "v165", "v166", "v167", "v168", "v169", "v170", "v171", "v172", \
"v173", "v174", "v175", "v176", "v177", "v178", "v179", "v180", "v181", \
"v182", "v183", "v184", "v185", "v186", "v187", "v188", "v189", "v190", \
"v191", "v192", "v193", "v194", "v195", "v196", "v197", "v198", "v199", \
"v200", "v201", "v202", "v203", "v204", "v205", "v206", "v207", "v208", \
"v209", "v210", "v211", "v212", "v213", "v214", "v215", "v216", "v217", \
"v218", "v219", "v220", "v221", "v222", "v223", "v224", "v225", "v226", \
"v227", "v228", "v229", "v230", "v231", "v232", "v233", "v234", "v235", \
"v236", "v237", "v238", "v239", "v240", "v241", "v242", "v243", "v244", \
"v245", "v246", "v247", "v248", "v249", "v250", "v251", "v252", "v253", \
"v254", "v255", \
"?ap0", "?ap1", "?fp0", "?fp1" }
#define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE, X, CODE)
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '^')
/* Register Arguments */
#ifndef USED_FOR_TARGET
#define GCN_KERNEL_ARG_TYPES 19
struct GTY(()) gcn_kernel_args
{
long requested;
int reg[GCN_KERNEL_ARG_TYPES];
int order[GCN_KERNEL_ARG_TYPES];
int nargs, nsgprs;
};
typedef struct gcn_args
{
/* True if this isn't a kernel (HSA runtime entrypoint). */
bool normal_function;
tree fntype;
struct gcn_kernel_args args;
int num;
int offset;
int alignment;
} CUMULATIVE_ARGS;
#endif
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \
gcn_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL), \
(N_NAMED_ARGS) != -1)
#ifndef USED_FOR_TARGET
#include "hash-table.h"
#include "hash-map.h"
#include "vec.h"
struct GTY(()) machine_function
{
struct gcn_kernel_args args;
int kernarg_segment_alignment;
int kernarg_segment_byte_size;
/* Frame layout info for normal functions. */
bool normal_function;
bool need_frame_pointer;
bool lr_needs_saving;
HOST_WIDE_INT outgoing_args_size;
HOST_WIDE_INT pretend_size;
HOST_WIDE_INT local_vars;
HOST_WIDE_INT callee_saves;
unsigned lds_allocated;
hash_map *lds_allocs;
vec *reduc_decls;
bool use_flat_addressing;
};
#endif
/* Codes for all the GCN builtins. */
enum gcn_builtin_codes
{
#define DEF_BUILTIN(fcode, icode, name, type, params, expander) \
GCN_BUILTIN_ ## fcode,
#define DEF_BUILTIN_BINOP_INT_FP(fcode, ic, name) \
GCN_BUILTIN_ ## fcode ## _V64SI, \
GCN_BUILTIN_ ## fcode ## _V64SI_unspec,
#include "gcn-builtins.def"
#undef DEF_BUILTIN
#undef DEF_BUILTIN_BINOP_INT_FP
GCN_BUILTIN_MAX
};
/* Misc */
/* We can load/store 128-bit quantities, but having this larger than
MAX_FIXED_MODE_SIZE (which we want to be 64 bits) causes problems. */
#define MOVE_MAX 8
#define AVOID_CCMODE_COPIES 1
#define SLOW_BYTE_ACCESS 0
#define WORD_REGISTER_OPERATIONS 1
/* Flag values are either BImode or DImode, but either way the compiler
should assume that all the bits are live. */
#define STORE_FLAG_VALUE -1
/* Definitions for register eliminations.
This is an array of structures. Each structure initializes one pair
of eliminable registers. The "from" register number is given first,
followed by "to". Eliminations of the same "from" register are listed
in order of preference. */
#define ELIMINABLE_REGS \
{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
{ ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
/* Define the offset between two registers, one to be eliminated, and the
other its replacement, at the start of a routine. */
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
((OFFSET) = gcn_initial_elimination_offset ((FROM), (TO)))
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
the value is constrained to be within the bounds of the declared
type, but kept valid in the wider mode. The signedness of the
extension may differ from that of the type. */
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& (TYPE == NULL || TREE_CODE (TYPE) != VECTOR_TYPE) \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
{ \
(MODE) = SImode; \
}
/* This needs to match gcn_function_value. */
#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, SGPR_REGNO (RETURN_VALUE_REG))
/* The s_ff0 and s_flbit instructions return -1 if no input bits are set. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2)
/* Costs. */
/* Branches are to be dicouraged when theres an alternative.
FIXME: This number is plucked from the air. */
#define BRANCH_COST(SPEED_P, PREDICABLE_P) 10
/* Profiling */
#define FUNCTION_PROFILER(FILE, LABELNO)
#define NO_PROFILE_COUNTERS 1
#define PROFILE_BEFORE_PROLOGUE 0
/* Trampolines */
#define TRAMPOLINE_SIZE 36
#define TRAMPOLINE_ALIGNMENT 64