| /* 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 |
| <http://www.gnu.org/licenses/>. */ |
| |
| #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<tree, int> *lds_allocs; |
| |
| vec<tree, va_gc> *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 |