1  /* Definitions for rtems targeting a PowerPC using elf.
       2     Copyright (C) 1996-2023 Free Software Foundation, Inc.
       3     Contributed by Joel Sherrill (joel@OARcorp.com).
       4  
       5     This file is part of GCC.
       6  
       7     GCC is free software; you can redistribute it and/or modify it
       8     under the terms of the GNU General Public License as published
       9     by the Free Software Foundation; either version 3, or (at your
      10     option) any later version.
      11  
      12     GCC is distributed in the hope that it will be useful, but WITHOUT
      13     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      14     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      15     License for more details.
      16  
      17     Under Section 7 of GPL version 3, you are granted additional
      18     permissions described in the GCC Runtime Library Exception, version
      19     3.1, as published by the Free Software Foundation.
      20  
      21     You should have received a copy of the GNU General Public License and
      22     a copy of the GCC Runtime Library Exception along with this program;
      23     see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      24     <http://www.gnu.org/licenses/>.  */
      25  
      26  /* Undef gnu-user.h macro we don't want.  */
      27  #undef CPLUSPLUS_CPP_SPEC
      28  
      29  /* Copy and paste from linux64.h and freebsd64.h */
      30  #ifdef IN_LIBGCC2
      31  #undef TARGET_64BIT
      32  #ifdef __powerpc64__
      33  #define TARGET_64BIT 1
      34  #else
      35  #define TARGET_64BIT 0
      36  #endif
      37  #endif
      38  
      39  /* Copy and paste from linux64.h and freebsd64.h */
      40  #undef	TARGET_AIX
      41  #define	TARGET_AIX TARGET_64BIT
      42  
      43  /* Simplified copy and paste from linux64.h and freebsd64.h */
      44  #undef DOT_SYMBOLS
      45  #define DOT_SYMBOLS 0
      46  
      47  /* Copy and paste from linux64.h and freebsd64.h */
      48  #undef TARGET_CMODEL
      49  #define TARGET_CMODEL rs6000_current_cmodel
      50  #define SET_CMODEL(opt) rs6000_current_cmodel = opt
      51  
      52  #undef TARGET_OS_CPP_BUILTINS
      53  #define TARGET_OS_CPP_BUILTINS()			\
      54    do							\
      55      {							\
      56        builtin_define ("__rtems__");			\
      57        builtin_define ("__USE_INIT_FINI__");		\
      58        builtin_assert ("system=rtems");			\
      59        if (TARGET_64BIT)					\
      60  	{						\
      61  	  builtin_define ("__PPC__");			\
      62  	  builtin_define ("__PPC64__");			\
      63  	  builtin_define ("__powerpc64__");		\
      64  	  builtin_assert ("cpu=powerpc64");		\
      65  	  builtin_assert ("machine=powerpc64");		\
      66  	}						\
      67        else						\
      68  	{						\
      69  	  builtin_define_std ("PPC");			\
      70  	  builtin_define_std ("powerpc");		\
      71  	  builtin_assert ("cpu=powerpc");		\
      72  	  builtin_assert ("machine=powerpc");		\
      73  	  TARGET_OS_SYSV_CPP_BUILTINS ();		\
      74  	}						\
      75      }							\
      76    while (0)
      77  
      78  /* Copy and paste from linux64.h and freebsd64.h */
      79  #undef RELOCATABLE_NEEDS_FIXUP
      80  #define RELOCATABLE_NEEDS_FIXUP \
      81    (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
      82  
      83  /* Copy and paste from linux64.h */
      84  #undef	RS6000_ABI_NAME
      85  #define	RS6000_ABI_NAME "linux"
      86  
      87  /* Copy and paste from linux64.h and freebsd64.h */
      88  #define INVALID_64BIT "%<-m%s%> not supported in this configuration"
      89  
      90  /* A lot of copy and paste from linux64.h and freebsd64.h */
      91  #undef	SUBSUBTARGET_OVERRIDE_OPTIONS
      92  #define	SUBSUBTARGET_OVERRIDE_OPTIONS				\
      93    do								\
      94      {								\
      95        if (rs6000_isa_flags & OPTION_MASK_64BIT)			\
      96  	{							\
      97  	  rs6000_elf_abi = 2;					\
      98  	  rs6000_current_abi = ABI_ELFv2;			\
      99  	  if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE)	\
     100  	    {							\
     101  	      rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE;	\
     102  	      error (INVALID_64BIT, "relocatable");		\
     103  	    }							\
     104  	  if (rs6000_isa_flags & OPTION_MASK_EABI)		\
     105  	    {							\
     106  	      rs6000_isa_flags &= ~OPTION_MASK_EABI;		\
     107  	      error (INVALID_64BIT, "eabi");			\
     108  	    }							\
     109  	  if (TARGET_PROTOTYPE)					\
     110  	    {							\
     111  	      target_prototype = 0;				\
     112  	      error (INVALID_64BIT, "prototype");		\
     113  	    }							\
     114  	  if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0)	\
     115  	    {							\
     116  	      rs6000_isa_flags |= OPTION_MASK_POWERPC64;	\
     117  	      error ("%<-m64%> requires a PowerPC64 cpu");		\
     118  	    }							\
     119  	  if ((rs6000_isa_flags_explicit			\
     120  		& OPTION_MASK_MINIMAL_TOC) != 0)		\
     121  	    {							\
     122  	      if (OPTION_SET_P (rs6000_current_cmodel)	\
     123  		  && rs6000_current_cmodel != CMODEL_SMALL)	\
     124  		error ("%<-mcmodel%> incompatible with other toc options"); \
     125  	      SET_CMODEL (CMODEL_SMALL);			\
     126  	    }							\
     127  	  else							\
     128  	    {							\
     129  	      if (!OPTION_SET_P (rs6000_current_cmodel))	\
     130  		SET_CMODEL (CMODEL_MEDIUM);			\
     131  	      if (rs6000_current_cmodel != CMODEL_SMALL)	\
     132  		{						\
     133  		  TARGET_NO_FP_IN_TOC = 0;			\
     134  		  TARGET_NO_SUM_IN_TOC = 0;			\
     135  		}						\
     136  	    }							\
     137  	}							\
     138      }								\
     139    while (0)
     140  
     141  #undef TARGET_LIBGCC_SDATA_SECTION
     142  #define TARGET_LIBGCC_SDATA_SECTION ".sdata"
     143  
     144  /* Copy and paste from linux64.h and freebsd64.h */
     145  #undef	SIZE_TYPE
     146  #define	SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
     147  
     148  /* Copy and paste from linux64.h and freebsd64.h */
     149  #undef	PTRDIFF_TYPE
     150  #define	PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
     151  
     152  /* Copy and paste from freebsd64.h */
     153  #undef WCHAR_TYPE
     154  
     155  /* Copy and paste from freebsd64.h */
     156  #undef  WCHAR_TYPE_SIZE
     157  #define WCHAR_TYPE_SIZE 32
     158  
     159  /* Copy and paste from linux64.h and freebsd64.h */
     160  #ifdef __powerpc64__
     161  #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
     162    asm (SECTION_OP "\n"					\
     163  "	bl " #FUNC "\n"					\
     164  "	nop\n"						\
     165  "	.previous");
     166  #endif
     167  
     168  /* This could be also POWERPC_FREEBSD.  It is related to the save/restore
     169     defines below.  */
     170  #define POWERPC_LINUX
     171  
     172  /* Copy and paste from linux64.h and freebsd64.h */
     173  #undef  SAVE_FP_PREFIX
     174  #define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
     175  #undef  SAVE_FP_SUFFIX
     176  #define SAVE_FP_SUFFIX ""
     177  #undef  RESTORE_FP_PREFIX
     178  #define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
     179  #undef  RESTORE_FP_SUFFIX
     180  #define RESTORE_FP_SUFFIX ""
     181  
     182  /* Copy and paste from linux64.h and freebsd64.h */
     183  #undef	ASM_PREFERRED_EH_DATA_FORMAT
     184  #define	ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
     185    (TARGET_64BIT || flag_pic						\
     186     ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel		\
     187        | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4))		\
     188     : DW_EH_PE_absptr)
     189  
     190  /* Copy and paste from linux64.h and freebsd64.h */
     191  #undef  TOC_SECTION_ASM_OP
     192  #define TOC_SECTION_ASM_OP \
     193    (TARGET_64BIT						\
     194     ? "\t.section\t\".toc\",\"aw\""			\
     195     : "\t.section\t\".got\",\"aw\"")
     196  
     197  /* Copy and paste from linux64.h and freebsd64.h */
     198  #undef  MINIMAL_TOC_SECTION_ASM_OP
     199  #define MINIMAL_TOC_SECTION_ASM_OP \
     200    (TARGET_64BIT						\
     201     ? "\t.section\t\".toc1\",\"aw\""			\
     202     : (flag_pic						\
     203        ? "\t.section\t\".got2\",\"aw\""			\
     204        : "\t.section\t\".got1\",\"aw\""))
     205  
     206  /* Copy and paste from linux64.h and freebsd64.h */
     207  #undef	ASM_DECLARE_FUNCTION_SIZE
     208  #define	ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)			\
     209    do									\
     210      {									\
     211        if (!flag_inhibit_size_directive)					\
     212  	{								\
     213  	  fputs ("\t.size\t", (FILE));					\
     214  	  if (TARGET_64BIT && DOT_SYMBOLS)				\
     215  	    putc ('.', (FILE));						\
     216  	  assemble_name ((FILE), (FNAME));				\
     217  	  fputs (",.-", (FILE));					\
     218  	  rs6000_output_function_entry (FILE, FNAME);			\
     219  	  putc ('\n', (FILE));						\
     220  	}								\
     221      }									\
     222    while (0)
     223  
     224  /* Copy and paste from linux64.h and freebsd64.h */
     225  #undef  ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
     226  #define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE)			\
     227    (TARGET_TOC								\
     228     && (SYMBOL_REF_P (X)							\
     229         || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS	\
     230  	   && SYMBOL_REF_P (XEXP (XEXP (X, 0), 0)))			\
     231         || GET_CODE (X) == LABEL_REF					\
     232         || (CONST_INT_P (X)						\
     233  	   && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode))	\
     234         || (CONST_DOUBLE_P (X)						\
     235  	   && ((TARGET_64BIT						\
     236  		&& (TARGET_MINIMAL_TOC					\
     237  		    || (SCALAR_FLOAT_MODE_P (GET_MODE (X))		\
     238  			&& ! TARGET_NO_FP_IN_TOC)))			\
     239  	       || (!TARGET_64BIT					\
     240  		   && !TARGET_NO_FP_IN_TOC				\
     241  		   && SCALAR_FLOAT_MODE_P (GET_MODE (X))		\
     242  		   && BITS_PER_WORD == HOST_BITS_PER_INT)))))
     243  
     244  #undef CPP_OS_DEFAULT_SPEC
     245  #define CPP_OS_DEFAULT_SPEC "\
     246  %{!mcpu*:  %{!Dppc*: %{!Dmpc*: -Dmpc750} } }\
     247  %{mcpu=403:  %{!Dppc*: %{!Dmpc*: -Dppc403}  } } \
     248  %{mcpu=505:  %{!Dppc*: %{!Dmpc*: -Dmpc505}  } } \
     249  %{mcpu=601:  %{!Dppc*: %{!Dmpc*: -Dppc601}  } } \
     250  %{mcpu=602:  %{!Dppc*: %{!Dmpc*: -Dppc602}  } } \
     251  %{mcpu=603:  %{!Dppc*: %{!Dmpc*: -Dppc603}  } } \
     252  %{mcpu=603e: %{!Dppc*: %{!Dmpc*: -Dppc603e} } } \
     253  %{mcpu=604:  %{!Dppc*: %{!Dmpc*: -Dmpc604}  } } \
     254  %{mcpu=750:  %{!Dppc*: %{!Dmpc*: -Dmpc750}  } } \
     255  %{mcpu=821:  %{!Dppc*: %{!Dmpc*: -Dmpc821}  } } \
     256  %{mcpu=860:  %{!Dppc*: %{!Dmpc*: -Dmpc860}  } } \
     257  %{mcpu=8540: %{!Dppc*: %{!Dmpc*: -Dppc8540}  } } \
     258  %{mcpu=e6500: -D__PPC_CPU_E6500__} \
     259  %{mvrsave: -D__PPC_VRSAVE__}"
     260  
     261  #undef	ASM_SPEC
     262  #define	ASM_SPEC "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
     263  
     264  #define ASM_SPEC32 "-a32 \
     265  %{mrelocatable} %{mrelocatable-lib} %{" FPIE_OR_FPIC_SPEC ":-K PIC} \
     266  %{memb|msdata=eabi: -memb}"
     267  
     268  #define ASM_SPEC64 "-a64"
     269  
     270  #define ASM_SPEC_COMMON "%(asm_cpu) \
     271  %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \
     272    ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
     273  
     274  #undef  LINK_OS_DEFAULT_SPEC
     275  #define LINK_OS_DEFAULT_SPEC \
     276  "%{!m64:%(link_os_spec32)}%{m64:%(link_os_spec64)}"
     277  
     278  #define LINK_OS_SPEC32 ENDIAN_SELECT(" -m elf32ppc",		\
     279  				     " -m elf32lppc",		\
     280  				     " -m elf32ppc")
     281  #define LINK_OS_SPEC64 ENDIAN_SELECT(" -m elf64ppc",		\
     282  				     " -m elf64lppc",		\
     283  				     " -m elf64ppc")
     284  
     285  #undef  SUBSUBTARGET_EXTRA_SPECS
     286  #define SUBSUBTARGET_EXTRA_SPECS \
     287    { "asm_spec_common",		ASM_SPEC_COMMON },			\
     288    { "asm_spec32",		ASM_SPEC32 },				\
     289    { "asm_spec64",		ASM_SPEC64 },				\
     290    { "link_os_spec32",		LINK_OS_SPEC32 },			\
     291    { "link_os_spec64",		LINK_OS_SPEC64 },
     292  
     293  /* Use gnu-user.h LINK_GCC_SEQUENCE_SPEC for rtems.  */
     294  #undef LINK_GCC_C_SEQUENCE_SPEC
     295  #define	LINK_GCC_C_SEQUENCE_SPEC \
     296    "%{mads|myellowknife|mmvme|msim:%G %L %G;" \
     297    "!mcall-*|mcall-linux:" GNU_USER_TARGET_LINK_GCC_C_SEQUENCE_SPEC ";" \
     298    ":%G %L %G}"
     299  
     300  #define RTEMS_STARTFILE_SPEC "ecrti%O%s rtems_crti%O%s crtbegin%O%s"
     301  #define RTEMS_ENDFILE_SPEC "crtend%O%s rtems_crtn%O%s ecrtn%O%s"