1  /* Definitions for 64-bit PowerPC running FreeBSD using the ELF format
       2     Copyright (C) 2012-2023 Free Software Foundation, Inc.
       3  
       4     This file is part of GCC.
       5  
       6     GCC is free software; you can redistribute it and/or modify it
       7     under the terms of the GNU General Public License as published
       8     by the Free Software Foundation; either version 3, or (at your
       9     option) any later version.
      10  
      11     GCC is distributed in the hope that it will be useful, but WITHOUT
      12     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      13     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      14     License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with GCC; see the file COPYING3.  If not see
      18     <http://www.gnu.org/licenses/>.  */
      19  
      20  /* Undef gnu-user.h macros we don't want.  */
      21  #undef CPLUSPLUS_CPP_SPEC
      22  #undef LINK_GCC_C_SEQUENCE_SPEC
      23  
      24  /* Override the defaults, which exist to force the proper definition.  */
      25  
      26  #ifdef IN_LIBGCC2
      27  #undef TARGET_64BIT
      28  #ifdef __powerpc64__
      29  #define TARGET_64BIT 1
      30  #else
      31  #define TARGET_64BIT 0
      32  #endif
      33  #endif
      34  
      35  #undef	TARGET_AIX
      36  #define	TARGET_AIX TARGET_64BIT
      37  
      38  #ifdef HAVE_LD_NO_DOT_SYMS
      39  /* New ABI uses a local sym for the function entry point.  */
      40  extern int dot_symbols;
      41  #undef DOT_SYMBOLS
      42  #define DOT_SYMBOLS dot_symbols
      43  #endif
      44  
      45  #define TARGET_USES_LINUX64_OPT 1
      46  #ifdef HAVE_LD_LARGE_TOC
      47  #undef TARGET_CMODEL
      48  #define TARGET_CMODEL rs6000_current_cmodel
      49  #define SET_CMODEL(opt) rs6000_current_cmodel = opt
      50  #else
      51  #define SET_CMODEL(opt) do {} while (0)
      52  #endif
      53  
      54  #undef  PROCESSOR_DEFAULT
      55  #define PROCESSOR_DEFAULT PROCESSOR_PPC7450
      56  #undef  PROCESSOR_DEFAULT64
      57  #define PROCESSOR_DEFAULT64 PROCESSOR_POWER8
      58  
      59  /* We don't need to generate entries in .fixup, except when
      60     -mrelocatable or -mrelocatable-lib is given.  */
      61  #undef RELOCATABLE_NEEDS_FIXUP
      62  #define RELOCATABLE_NEEDS_FIXUP \
      63    (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
      64  
      65  #undef  RS6000_ABI_NAME
      66  #define RS6000_ABI_NAME "freebsd"
      67  
      68  #define INVALID_64BIT "-m%s not supported in this configuration"
      69  #define INVALID_32BIT INVALID_64BIT
      70  
      71  /* Use LINUX64 instead of FREEBSD64 for compat with e.g. sysv4le.h */
      72  #ifdef LINUX64_DEFAULT_ABI_ELFv2
      73  #define ELFv2_ABI_CHECK (rs6000_elf_abi != 1)
      74  #else
      75  #define ELFv2_ABI_CHECK (rs6000_elf_abi == 2)
      76  #endif
      77  
      78  #undef  SUBSUBTARGET_OVERRIDE_OPTIONS
      79  #define SUBSUBTARGET_OVERRIDE_OPTIONS				\
      80    do rs6000_linux64_override_options (); while (0)
      81  
      82  #undef	ASM_SPEC
      83  #undef	LINK_OS_FREEBSD_SPEC
      84  
      85  #define	ASM_SPEC	 "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
      86  #define	LINK_OS_FREEBSD_SPEC "%{m32:%(link_os_freebsd_spec32)}%{!m32:%(link_os_freebsd_spec64)}"
      87  
      88  #define ASM_SPEC32 "-a32 \
      89  %{mrelocatable} %{mrelocatable-lib} %{" FPIE_OR_FPIC_SPEC ":-K PIC} \
      90  %{memb} %{!memb: %{msdata=eabi: -memb}} \
      91  %{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
      92      %{mcall-freebsd: -mbig} \
      93      %{mcall-i960-old: -mlittle} \
      94      %{mcall-linux: -mbig} \
      95      %{mcall-gnu: -mbig} \
      96      %{mcall-netbsd: -mbig} \
      97  }}}}"
      98  
      99  #define ASM_SPEC64 "-a64"
     100  
     101  #define ASM_SPEC_COMMON "%(asm_cpu) \
     102  %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \
     103    ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
     104  
     105  #undef	SUBSUBTARGET_EXTRA_SPECS
     106  #define SUBSUBTARGET_EXTRA_SPECS					\
     107    { "asm_spec_common",		ASM_SPEC_COMMON },			\
     108    { "asm_spec32",		ASM_SPEC32 },				\
     109    { "asm_spec64",		ASM_SPEC64 },				\
     110    { "link_os_freebsd_spec32",	LINK_OS_FREEBSD_SPEC32 },     		\
     111    { "link_os_freebsd_spec64",	LINK_OS_FREEBSD_SPEC64 },
     112  
     113  #define LINK_OS_FREEBSD_SPEC_DEF "\
     114    %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
     115    %{v:-V} \
     116    %{assert*} %{R*} %{rpath*} %{defsym*} \
     117    %{shared:-Bshareable %{h*} %{soname*}} \
     118    %{!shared: \
     119      %{!static: \
     120        %{rdynamic: -export-dynamic} \
     121        %{!dynamic-linker:-dynamic-linker " FBSD_DYNAMIC_LINKER "}} \
     122      %{static:-Bstatic}} \
     123    %{symbolic:-Bsymbolic}"
     124  
     125  #undef  DEFAULT_ASM_ENDIAN
     126  #define LINK_OS_FREEBSD_SPEC32 "-melf32ppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF
     127  #if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
     128  #define DEFAULT_ASM_ENDIAN " -mlittle"
     129  #define LINK_OS_FREEBSD_SPEC64 "-melf64lppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF
     130  #else
     131  #define DEFAULT_ASM_ENDIAN " -mbig"
     132  #define LINK_OS_FREEBSD_SPEC64 "-melf64ppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF
     133  #endif
     134  
     135  #undef	MULTILIB_DEFAULTS
     136  #define MULTILIB_DEFAULTS { "m64" }
     137  
     138  /* PowerPC-64 FreeBSD increases natural record alignment to doubleword if
     139     the first field is an FP double, only if in power alignment mode.  */
     140  #undef  ROUND_TYPE_ALIGN
     141  #define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)			\
     142    ((TARGET_64BIT							\
     143      && (TREE_CODE (STRUCT) == RECORD_TYPE				\
     144  	|| TREE_CODE (STRUCT) == UNION_TYPE				\
     145  	|| TREE_CODE (STRUCT) == QUAL_UNION_TYPE)			\
     146      && TARGET_ALIGN_NATURAL == 0)					\
     147     ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED)	\
     148     : MAX ((COMPUTED), (SPECIFIED)))
     149  
     150  /* Use the default for compiling target libs.  */
     151  #ifdef IN_TARGET_LIBS
     152  #undef TARGET_ALIGN_NATURAL
     153  #define TARGET_ALIGN_NATURAL 1
     154  #endif
     155  
     156  /* Indicate that jump tables go in the text section.  */
     157  #undef  JUMP_TABLES_IN_TEXT_SECTION
     158  #define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
     159  
     160  /* The linux ppc64 ABI isn't explicit on whether aggregates smaller
     161     than a doubleword should be padded upward or downward.  You could
     162     reasonably assume that they follow the normal rules for structure
     163     layout treating the parameter area as any other block of memory,
     164     then map the reg param area to registers.  i.e. pad upward.
     165     Setting both of the following defines results in this behavior.
     166     Setting just the first one will result in aggregates that fit in a
     167     doubleword being padded downward, and others being padded upward.
     168     Not a bad idea as this results in struct { int x; } being passed
     169     the same way as an int.  */
     170  #define AGGREGATE_PADDING_FIXED TARGET_64BIT
     171  #define AGGREGATES_PAD_UPWARD_ALWAYS 0
     172  
     173  /* Specify padding for the last element of a block move between
     174     registers and memory.  FIRST is nonzero if this is the only
     175     element.  */
     176  #define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
     177    (!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
     178  
     179  /* FreeBSD doesn't support saving and restoring 64-bit regs with a 32-bit
     180     kernel. This is supported when running on a 64-bit kernel with
     181     COMPAT_FREEBSD32, but tell GCC it isn't so that our 32-bit binaries
     182     are compatible. */
     183  #define OS_MISSING_POWERPC64 !TARGET_64BIT
     184  
     185  #undef  FBSD_TARGET_CPU_CPP_BUILTINS
     186  #define FBSD_TARGET_CPU_CPP_BUILTINS()			\
     187    do							\
     188      {							\
     189        builtin_define ("__PPC__");			\
     190        builtin_define ("__ppc__");			\
     191        builtin_define ("__powerpc__");			\
     192        if (TARGET_64BIT)					\
     193  	{						\
     194  	  builtin_define ("__arch64__");		\
     195  	  builtin_define ("__LP64__");			\
     196  	  builtin_define ("__PPC64__");			\
     197  	  builtin_define ("__powerpc64__");		\
     198  	  builtin_assert ("cpu=powerpc64");		\
     199  	  builtin_assert ("machine=powerpc64");		\
     200  	}						\
     201        else						\
     202  	{						\
     203  	  builtin_define_std ("PPC");			\
     204  	  builtin_define_std ("powerpc");		\
     205  	  builtin_assert ("cpu=powerpc");		\
     206  	  builtin_assert ("machine=powerpc");		\
     207  	  TARGET_OS_SYSV_CPP_BUILTINS ();		\
     208  	}						\
     209      }							\
     210    while (0)
     211  
     212  #undef	CPP_OS_DEFAULT_SPEC
     213  #define CPP_OS_DEFAULT_SPEC "%(cpp_os_freebsd)"
     214  
     215  #undef CPP_OS_FREEBSD_SPEC
     216  #define CPP_OS_FREEBSD_SPEC ""
     217  
     218  #undef	STARTFILE_DEFAULT_SPEC
     219  #define STARTFILE_DEFAULT_SPEC "%(startfile_freebsd)"
     220  
     221  #undef	ENDFILE_DEFAULT_SPEC
     222  #define ENDFILE_DEFAULT_SPEC "%(endfile_freebsd)"
     223  
     224  #undef	LIB_DEFAULT_SPEC
     225  #define LIB_DEFAULT_SPEC "%(lib_freebsd)"
     226  
     227  #undef	LINK_START_DEFAULT_SPEC
     228  #define LINK_START_DEFAULT_SPEC "%(link_start_freebsd)"
     229  
     230  #undef	LINK_OS_DEFAULT_SPEC
     231  #define	LINK_OS_DEFAULT_SPEC "%(link_os_freebsd)"
     232  
     233  /* XXX: This is wrong for many platforms in sysv4.h.
     234     We should work on getting that definition fixed.  */
     235  #undef  LINK_SHLIB_SPEC
     236  #define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
     237  
     238  
     239  /************************[  Target stuff  ]***********************************/
     240  
     241  /* Define the actual types of some ANSI-mandated types.  
     242     Needs to agree with <machine/ansi.h>.  GCC defaults come from c-decl.cc,
     243     c-common.cc, and config/<arch>/<arch>.h.  */
     244  
     245  
     246  #undef  SIZE_TYPE
     247  #define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
     248  
     249  #undef  PTRDIFF_TYPE
     250  #define PTRDIFF_TYPE	(TARGET_64BIT ? "long int" : "int")
     251  
     252  /* rs6000.h gets this wrong for FreeBSD.  We use the GCC defaults instead.  */
     253  #undef WCHAR_TYPE
     254  
     255  #undef  WCHAR_TYPE_SIZE
     256  #define WCHAR_TYPE_SIZE 32
     257  
     258  /* Function profiling bits */
     259  #undef  RS6000_MCOUNT
     260  #define RS6000_MCOUNT "_mcount"
     261  
     262  #define PROFILE_HOOK(LABEL) \
     263    do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
     264  
     265  /* _init and _fini functions are built from bits spread across many
     266     object files, each potentially with a different TOC pointer.  For
     267     that reason, place a nop after the call so that the linker can
     268     restore the TOC pointer if a TOC adjusting call stub is needed.  */
     269  #ifdef __powerpc64__
     270  #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
     271    asm (SECTION_OP "\n"					\
     272  "	bl " #FUNC "\n"					\
     273  "	nop\n"						\
     274  "	.previous");
     275  #endif
     276  
     277  /* FP save and restore routines.  */
     278  #undef  SAVE_FP_PREFIX
     279  #define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
     280  #undef  SAVE_FP_SUFFIX
     281  #define SAVE_FP_SUFFIX ""
     282  #undef  RESTORE_FP_PREFIX
     283  #define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
     284  #undef  RESTORE_FP_SUFFIX
     285  #define RESTORE_FP_SUFFIX ""
     286  
     287  /* Select a format to encode pointers in exception handling data.  CODE
     288     is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
     289     true if the symbol may be affected by dynamic relocations.  */
     290  #undef	ASM_PREFERRED_EH_DATA_FORMAT
     291  #define	ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
     292    (TARGET_64BIT || flag_pic						\
     293     ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel		\
     294        | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4))		\
     295     : DW_EH_PE_absptr)
     296  
     297  /* Static stack checking is supported by means of probes.  */
     298  #define STACK_CHECK_STATIC_BUILTIN 1
     299  
     300  /* The default value isn't sufficient in 64-bit mode.  */
     301  #define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024)
     302  
     303  /* Use standard DWARF numbering for DWARF debugging information.  */
     304  #define RS6000_USE_DWARF_NUMBERING
     305  
     306  /* PowerPC64 Linux word-aligns FP doubles when -malign-power is given.  */
     307  #undef  ADJUST_FIELD_ALIGN
     308  #define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \
     309    ((TARGET_64BIT							\
     310      && TARGET_ALIGN_NATURAL == 0					\
     311      && TYPE_MODE (strip_array_types (TYPE)) == DFmode)   		\
     312     ? MIN ((COMPUTED), 32)						\
     313     : (COMPUTED))
     314  
     315  #undef  TOC_SECTION_ASM_OP
     316  #define TOC_SECTION_ASM_OP \
     317    (TARGET_64BIT                                         \
     318     ? "\t.section\t\".toc\",\"aw\""                      \
     319     : "\t.section\t\".got\",\"aw\"")
     320  
     321  #undef  MINIMAL_TOC_SECTION_ASM_OP
     322  #define MINIMAL_TOC_SECTION_ASM_OP \
     323    (TARGET_64BIT                                         \
     324     ? "\t.section\t\".toc1\",\"aw\""                     \
     325     : (flag_pic						\
     326        ? "\t.section\t\".got2\",\"aw\""                  \
     327        : "\t.section\t\".got1\",\"aw\""))
     328  
     329  /* This is how to declare the size of a function.  */
     330  #undef  ASM_DECLARE_FUNCTION_SIZE
     331  #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                    \
     332    do                                                                    \
     333      {                                                                   \
     334        if (!flag_inhibit_size_directive)                                 \
     335          {                                                               \
     336            fputs ("\t.size\t", (FILE));                                  \
     337            if (TARGET_64BIT && DOT_SYMBOLS)                              \
     338              putc ('.', (FILE));                                         \
     339            assemble_name ((FILE), (FNAME));                              \
     340            fputs (",.-", (FILE));                                        \
     341            rs6000_output_function_entry (FILE, FNAME);                   \
     342            putc ('\n', (FILE));                                          \
     343          }                                                               \
     344      }                                                                   \
     345    while (0)
     346  
     347  #undef  ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
     348  #define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE)                        \
     349    (TARGET_TOC                                                           \
     350     && (SYMBOL_REF_P (X)							\
     351         || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS      \
     352             && SYMBOL_REF_P (XEXP (XEXP (X, 0), 0)))			\
     353         || GET_CODE (X) == LABEL_REF                                     \
     354         || (CONST_INT_P (X)						\
     355             && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode))      \
     356         || (CONST_DOUBLE_P (X)						\
     357             && ((TARGET_64BIT                                            \
     358                  && (TARGET_MINIMAL_TOC                                  \
     359                      || (SCALAR_FLOAT_MODE_P (GET_MODE (X))              \
     360                          && ! TARGET_NO_FP_IN_TOC)))                     \
     361                 || (!TARGET_64BIT                                        \
     362                     && !TARGET_NO_FP_IN_TOC                              \
     363                     && SCALAR_FLOAT_MODE_P (GET_MODE (X))                \
     364                     && BITS_PER_WORD == HOST_BITS_PER_INT)))))
     365  
     366  /* Use --as-needed -lgcc_s for eh support.  */
     367  #ifdef HAVE_LD_AS_NEEDED
     368  #define USE_LD_AS_NEEDED 1
     369  #endif
     370  
     371  #define POWERPC_FREEBSD