+// SPDX-License-Identifier: GPL-3.0-or-later
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000-2023 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC 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, or (at your
+ option) any later version.
-GNU CC 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.
+ GCC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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/>. */
/* Yes! We are AIX! */
#define DEFAULT_ABI ABI_AIX
-#undef TARGET_AIX
+#undef TARGET_AIX
#define TARGET_AIX 1
+
+/* Linux64.h wants to redefine TARGET_AIX based on -m64, but it can't be used
+ in the #if conditional in options-default.h, so provide another macro. */
+#undef TARGET_AIX_OS
+#define TARGET_AIX_OS 1
+
+/* AIX always has a TOC. */
+#define TARGET_HAS_TOC 1
+#define FIXED_R2 1
+
+/* AIX allows r13 to be used in 32-bit mode. */
+#define FIXED_R13 0
+
+/* 32-bit and 64-bit AIX stack boundary is 128. */
+#undef STACK_BOUNDARY
+#define STACK_BOUNDARY 128
+
+/* Offset within stack frame to start allocating local variables at.
+ If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
+ first local allocated. Otherwise, it is the offset to the BEGINNING
+ of the first local allocated.
+
+ On the RS/6000, the frame pointer is the same as the stack pointer,
+ except for dynamic allocations. So we start after the fixed area and
+ outgoing parameter area.
+
+ If the function uses dynamic stack space (CALLS_ALLOCA is set), that
+ space needs to be aligned to STACK_BOUNDARY, i.e. the sum of the
+ sizes of the fixed area and the parameter area must be a multiple of
+ STACK_BOUNDARY. */
+
+#undef RS6000_STARTING_FRAME_OFFSET
+#define RS6000_STARTING_FRAME_OFFSET \
+ (cfun->calls_alloca \
+ ? RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, 16) \
+ : (RS6000_ALIGN (crtl->outgoing_args_size, 16) + RS6000_SAVE_AREA))
+
+/* Offset from the stack pointer register to an item dynamically
+ allocated on the stack, e.g., by `alloca'.
+
+ The default value for this macro is `STACK_POINTER_OFFSET' plus the
+ length of the outgoing arguments. The default is correct for most
+ machines. See `function.cc' for details.
+
+ This value must be a multiple of STACK_BOUNDARY (hard coded in
+ `emit-rtl.cc'). */
+#undef STACK_DYNAMIC_OFFSET
+#define STACK_DYNAMIC_OFFSET(FUNDECL) \
+ RS6000_ALIGN (crtl->outgoing_args_size.to_constant () \
+ + STACK_POINTER_OFFSET, 16)
+
+#undef TARGET_IEEEQUAD
+#define TARGET_IEEEQUAD 0
+
+#undef TARGET_IEEEQUAD_DEFAULT
+#define TARGET_IEEEQUAD_DEFAULT 0
+
/* The AIX linker will discard static constructors in object files before
collect has a chance to see them, so scan the object files directly. */
#define COLLECT_EXPORT_LIST
-/* Handle #pragma weak and #pragma pack. */
-#define HANDLE_SYSV_PRAGMA
+/* On AIX, initialisers specified with -binitfini are called in breadth-first
+ order.
+ e.g. if a.out depends on lib1.so, the init function for a.out is called before
+ the init function for lib1.so.
+
+ To ensure global C++ constructors in linked libraries are run before global
+ C++ constructors from the current module, there is additional symbol scanning
+ logic in collect2.
+
+ The global initialiser/finaliser functions are named __GLOBAL_AIXI_{libname}
+ and __GLOBAL_AIXD_{libname} and are exported from each shared library.
+
+ collect2 will detect these symbols when they exist in shared libraries that
+ the current program is being linked against. All such initiliser functions
+ will be called prior to the constructors of the current program, and
+ finaliser functions called after destructors.
+
+ Reference counting generated by collect2 will ensure that constructors are
+ only invoked once in the case of multiple dependencies on a library.
+
+ -binitfini is still used in parallel to this solution.
+ This handles the case where a library is loaded through dlopen(), and also
+ handles the option -blazy.
+*/
+#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
+ fprintf ((STREAM), "void %s() {\n\t%s();\n}\n", aix_shared_initname, (FUNC))
+#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
+ fprintf ((STREAM), "void %s() {\n\t%s();\n}\n", aix_shared_fininame, (FUNC))
+
+#if HAVE_AS_REF
+/* Issue assembly directives that create a reference to the given DWARF table
+ identifier label from the current function section. This is defined to
+ ensure we drag frame tables associated with needed function bodies in
+ a link with garbage collection activated. */
+#define ASM_OUTPUT_DWARF_TABLE_REF rs6000_aix_asm_output_dwarf_table_ref
+#endif
/* This is the only version of nm that collect2 can work with. */
#define REAL_NM_FILE_NAME "/usr/ucb/nm"
#define USER_LABEL_PREFIX ""
+
/* Don't turn -B into -L if the argument specifies a relative file name. */
#define RELATIVE_PREFIX_NOT_LINKDIR
#define LINK_LIBGCC_SPECIAL_1
/* Names to predefine in the preprocessor for this target machine. */
-#define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("_IBMR2"); \
- builtin_define ("_POWER"); \
- builtin_define ("_AIX"); \
- builtin_define ("_AIX32"); \
- builtin_define ("_LONG_LONG"); \
- builtin_assert ("system=unix"); \
- builtin_assert ("system=aix"); \
- builtin_assert ("cpu=rs6000"); \
- builtin_assert ("machine=rs6000"); \
- } \
+#define TARGET_OS_AIX_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("_IBMR2"); \
+ builtin_define ("_POWER"); \
+ builtin_define ("__unix__"); \
+ builtin_define ("_AIX"); \
+ builtin_define ("_AIX32"); \
+ builtin_define ("_AIX41"); \
+ builtin_define ("_LONG_LONG"); \
+ if (TARGET_LONG_DOUBLE_128) \
+ builtin_define ("__LONGDOUBLE128"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=aix"); \
+ if (TARGET_64BIT) \
+ { \
+ builtin_define ("__PPC__"); \
+ builtin_define ("__PPC64__"); \
+ builtin_define ("__powerpc__"); \
+ builtin_define ("__powerpc64__"); \
+ builtin_assert ("cpu=powerpc64"); \
+ builtin_assert ("machine=powerpc64"); \
+ } \
+ else \
+ { \
+ builtin_define ("__PPC__"); \
+ builtin_define ("__powerpc__"); \
+ builtin_assert ("cpu=powerpc"); \
+ builtin_assert ("machine=powerpc"); \
+ } \
+ } \
while (0)
/* Define appropriate architecture macros for preprocessor depending on
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
%{ansi: -D_ANSI_C_SOURCE}"
+#define CC1_SPEC "%(cc1_cpu)"
+
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC ""
Don't do this until the fixed IBM assembler is more generally available.
When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL,
ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no
- longer be needed. Also, the extern declaration of mcount in ASM_FILE_START
- will no longer be needed. */
+ longer be needed. Also, the extern declaration of mcount in
+ rs6000_xcoff_file_start will no longer be needed. */
/* #define ASM_SPEC "-u %(asm_cpu)" */
/* Default location of syscalls.exp under AIX */
-#ifndef CROSS_COMPILE
-#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp"
-#else
-#define LINK_SYSCALLS_SPEC ""
-#endif
+#define LINK_SYSCALLS_SPEC "-bI:%R/lib/syscalls.exp"
/* Default location of libg.exp under AIX */
-#ifndef CROSS_COMPILE
-#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp"
-#else
-#define LINK_LIBG_SPEC ""
-#endif
+#define LINK_LIBG_SPEC "-bexport:%R/usr/lib/libg.exp"
/* Define the options for the binder: Start text at 512, align all segments
to 512 bytes, and warn if there is text relocation.
%{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}"
/* Profiled library versions are used by linking with special directories. */
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-%{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+%{p:-L%R/lib/profiled -L%R/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
+/* Static linking with shared libstdc++ requires libsupc++ as well. */
+#define LIBSTDCXX_STATIC "supc++"
+
+/* This now supports a natural alignment mode. */
/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
- (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
- ? get_inner_array_type (FIELD) \
- : TREE_TYPE (FIELD)) == DFmode \
- ? MIN ((COMPUTED), 32) : (COMPUTED))
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \
+ (TARGET_ALIGN_NATURAL == 0 \
+ ? rs6000_special_adjust_field_align (TYPE, COMPUTED) \
+ : (COMPUTED))
/* AIX increases natural record alignment to doubleword if the first
field is an FP double while the FP fields remain word aligned. */
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
- ((TREE_CODE (STRUCT) == RECORD_TYPE \
- || TREE_CODE (STRUCT) == UNION_TYPE \
- || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
- && TYPE_FIELDS (STRUCT) != 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
+ ((TREE_CODE (STRUCT) == RECORD_TYPE \
+ || TREE_CODE (STRUCT) == UNION_TYPE \
+ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
+ && TARGET_ALIGN_NATURAL == 0 \
+ ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
: MAX ((COMPUTED), (SPECIFIED)))
-
+/* The AIX ABI isn't explicit on whether aggregates smaller than a
+ word/doubleword should be padded upward or downward. One could
+ reasonably assume that they follow the normal rules for structure
+ layout treating the parameter area as any other block of memory,
+ then map the reg param area to registers, i.e., pad upward, which
+ is the way IBM Compilers for AIX behave.
+ Setting both of the following defines results in this behavior. */
+#define AGGREGATE_PADDING_FIXED 1
+#define AGGREGATES_PAD_UPWARD_ALWAYS 1
+
+/* Specify padding for the last element of a block move between
+ registers and memory. FIRST is nonzero if this is the only
+ element. */
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
+ (!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
/* Indicate that jump tables go in the text section. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
-/* Enable AIX XL compiler calling convention breakage compatibility. */
-#undef TARGET_XL_CALL
-#define MASK_XL_CALL 0x40000000
-#define TARGET_XL_CALL (target_flags & MASK_XL_CALL)
-#undef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES \
- {"xl-call", MASK_XL_CALL, \
- N_("Always pass floating-point arguments in memory") }, \
- {"no-xl-call", - MASK_XL_CALL, \
- N_("Don't always pass floating-point arguments in memory") }, \
- SUBSUBTARGET_SWITCHES
-#define SUBSUBTARGET_SWITCHES
-
/* Define any extra SPECS that the compiler needs to generate. */
#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "link_syscalls", LINK_SYSCALLS_SPEC }, \
{ "link_libg", LINK_LIBG_SPEC }
-/* Define cutoff for using external functions to save floating point. */
-#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
-
-/* Optabs entries for the int->float routines and quad FP operations
- using the standard AIX names. */
-#define ADDTF3_LIBCALL "_xlqadd"
-#define DIVTF3_LIBCALL "_xlqdiv"
-#define MULTF3_LIBCALL "_xlqmul"
-#define SUBTF3_LIBCALL "_xlqsub"
-
-#define INIT_TARGET_OPTABS \
- do { \
- if (! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT) \
- { \
- fixdfsi_libfunc = init_one_libfunc (RS6000_ITRUNC); \
- fixunsdfsi_libfunc = init_one_libfunc (RS6000_UITRUNC); \
- } \
- if (TARGET_HARD_FLOAT) \
- { \
- add_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (ADDTF3_LIBCALL); \
- sub_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (SUBTF3_LIBCALL); \
- smul_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (MULTF3_LIBCALL); \
- sdiv_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (DIVTF3_LIBCALL); \
- } \
- } while (0)
+#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL)
-/* AIX always has a TOC. */
-#define TARGET_NO_TOC 0
-#define TARGET_TOC 1
+/* No version of AIX fully supports AltiVec or 64-bit instructions in
+ 32-bit mode. */
+#define OS_MISSING_POWERPC64 1
+#define OS_MISSING_ALTIVEC 1
-#define FIXED_R2 1
-/* AIX allows r13 to be used. */
-#define FIXED_R13 0
+/* WINT_TYPE */
+#define WINT_TYPE "int"
-/* __throw will restore its own return address to be the same as the
- return address of the function that the throw is being made to.
- This is unfortunate, because we want to check the original
- return address to see if we need to restore the TOC.
- So we have to squirrel it away with this. */
-#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+/* Static stack checking is supported by means of probes. */
+#define STACK_CHECK_STATIC_BUILTIN 1
-#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL)
+/* Use standard DWARF numbering for DWARF debugging information. */
+#define RS6000_USE_DWARF_NUMBERING
+
+#define TARGET_PRECOMPUTE_TLS_P rs6000_aix_precompute_tls_p
-/* Print subsidiary information on the compiler version in use. */
-#define TARGET_VERSION ;
+/* Replace -m64 with -maix64 and -m32 with -maix32. */
+#undef SUBTARGET_DRIVER_SELF_SPECS
+#define SUBTARGET_DRIVER_SELF_SPECS \
+"%{m64:-maix64} %<m64", \
+"%{m32:-maix32} %<m32"