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