18dd4bdcdSmrg /* Common hooks for IBM RS/6000.
2*760c2415Smrg Copyright (C) 1991-2019 Free Software Foundation, Inc.
38dd4bdcdSmrg
48dd4bdcdSmrg This file is part of GCC.
58dd4bdcdSmrg
68dd4bdcdSmrg GCC is free software; you can redistribute it and/or modify it
78dd4bdcdSmrg under the terms of the GNU General Public License as published
88dd4bdcdSmrg by the Free Software Foundation; either version 3, or (at your
98dd4bdcdSmrg option) any later version.
108dd4bdcdSmrg
118dd4bdcdSmrg GCC is distributed in the hope that it will be useful, but WITHOUT
128dd4bdcdSmrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
138dd4bdcdSmrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
148dd4bdcdSmrg License for more details.
158dd4bdcdSmrg
168dd4bdcdSmrg You should have received a copy of the GNU General Public License
178dd4bdcdSmrg along with GCC; see the file COPYING3. If not see
188dd4bdcdSmrg <http://www.gnu.org/licenses/>. */
198dd4bdcdSmrg
208dd4bdcdSmrg #include "config.h"
218dd4bdcdSmrg #include "system.h"
228dd4bdcdSmrg #include "coretypes.h"
238dd4bdcdSmrg #include "diagnostic-core.h"
248dd4bdcdSmrg #include "tm.h"
258dd4bdcdSmrg #include "common/common-target.h"
268dd4bdcdSmrg #include "common/common-target-def.h"
278dd4bdcdSmrg #include "opts.h"
288dd4bdcdSmrg #include "flags.h"
298dd4bdcdSmrg #include "params.h"
308dd4bdcdSmrg
318dd4bdcdSmrg /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
328dd4bdcdSmrg static const struct default_options rs6000_option_optimization_table[] =
338dd4bdcdSmrg {
348dd4bdcdSmrg /* Enable -fsched-pressure for first pass instruction scheduling. */
358dd4bdcdSmrg { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
368dd4bdcdSmrg { OPT_LEVELS_NONE, 0, NULL, 0 }
378dd4bdcdSmrg };
388dd4bdcdSmrg
398dd4bdcdSmrg /* Implement TARGET_OPTION_INIT_STRUCT. */
408dd4bdcdSmrg
418dd4bdcdSmrg static void
rs6000_option_init_struct(struct gcc_options * opts)428dd4bdcdSmrg rs6000_option_init_struct (struct gcc_options *opts)
438dd4bdcdSmrg {
448dd4bdcdSmrg if (DEFAULT_ABI == ABI_DARWIN)
458dd4bdcdSmrg /* The Darwin libraries never set errno, so we might as well
468dd4bdcdSmrg avoid calling them when that's the only reason we would. */
478dd4bdcdSmrg opts->x_flag_errno_math = 0;
488dd4bdcdSmrg
498dd4bdcdSmrg /* Enable section anchors by default. */
508dd4bdcdSmrg if (!TARGET_MACHO)
518dd4bdcdSmrg opts->x_flag_section_anchors = 1;
528dd4bdcdSmrg }
538dd4bdcdSmrg
548dd4bdcdSmrg /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
558dd4bdcdSmrg
568dd4bdcdSmrg static void
rs6000_option_default_params(void)578dd4bdcdSmrg rs6000_option_default_params (void)
588dd4bdcdSmrg {
598dd4bdcdSmrg /* Double growth factor to counter reduced min jump length. */
608dd4bdcdSmrg set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
618dd4bdcdSmrg }
628dd4bdcdSmrg
638dd4bdcdSmrg /* If not otherwise specified by a target, make 'long double' equivalent to
648dd4bdcdSmrg 'double'. */
658dd4bdcdSmrg
668dd4bdcdSmrg #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
678dd4bdcdSmrg #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
688dd4bdcdSmrg #endif
698dd4bdcdSmrg
708dd4bdcdSmrg /* Implement TARGET_HANDLE_OPTION. */
718dd4bdcdSmrg
728dd4bdcdSmrg static bool
rs6000_handle_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct cl_decoded_option * decoded,location_t loc)738dd4bdcdSmrg rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
748dd4bdcdSmrg const struct cl_decoded_option *decoded,
758dd4bdcdSmrg location_t loc)
768dd4bdcdSmrg {
778dd4bdcdSmrg enum fpu_type_t fpu_type = FPU_NONE;
788dd4bdcdSmrg char *p, *q;
798dd4bdcdSmrg size_t code = decoded->opt_index;
808dd4bdcdSmrg const char *arg = decoded->arg;
818dd4bdcdSmrg int value = decoded->value;
828dd4bdcdSmrg
838dd4bdcdSmrg switch (code)
848dd4bdcdSmrg {
858dd4bdcdSmrg case OPT_mfull_toc:
868dd4bdcdSmrg opts->x_rs6000_isa_flags &= ~OPTION_MASK_MINIMAL_TOC;
878dd4bdcdSmrg opts->x_TARGET_NO_FP_IN_TOC = 0;
888dd4bdcdSmrg opts->x_TARGET_NO_SUM_IN_TOC = 0;
898dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
908dd4bdcdSmrg #ifdef TARGET_USES_SYSV4_OPT
918dd4bdcdSmrg /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
928dd4bdcdSmrg just the same as -mminimal-toc. */
938dd4bdcdSmrg opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
948dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
958dd4bdcdSmrg #endif
968dd4bdcdSmrg break;
978dd4bdcdSmrg
988dd4bdcdSmrg #ifdef TARGET_USES_SYSV4_OPT
998dd4bdcdSmrg case OPT_mtoc:
1008dd4bdcdSmrg /* Make -mtoc behave like -mminimal-toc. */
1018dd4bdcdSmrg opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
1028dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
1038dd4bdcdSmrg break;
1048dd4bdcdSmrg #endif
1058dd4bdcdSmrg
1068dd4bdcdSmrg #ifdef TARGET_USES_AIX64_OPT
1078dd4bdcdSmrg case OPT_maix64:
1088dd4bdcdSmrg #else
1098dd4bdcdSmrg case OPT_m64:
1108dd4bdcdSmrg #endif
1118dd4bdcdSmrg opts->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64;
1128dd4bdcdSmrg opts->x_rs6000_isa_flags |= (~opts_set->x_rs6000_isa_flags
1138dd4bdcdSmrg & OPTION_MASK_PPC_GFXOPT);
1148dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64;
1158dd4bdcdSmrg break;
1168dd4bdcdSmrg
1178dd4bdcdSmrg #ifdef TARGET_USES_AIX64_OPT
1188dd4bdcdSmrg case OPT_maix32:
1198dd4bdcdSmrg #else
1208dd4bdcdSmrg case OPT_m32:
1218dd4bdcdSmrg #endif
1228dd4bdcdSmrg opts->x_rs6000_isa_flags &= ~OPTION_MASK_POWERPC64;
1238dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64;
1248dd4bdcdSmrg break;
1258dd4bdcdSmrg
1268dd4bdcdSmrg case OPT_mminimal_toc:
1278dd4bdcdSmrg if (value == 1)
1288dd4bdcdSmrg {
1298dd4bdcdSmrg opts->x_TARGET_NO_FP_IN_TOC = 0;
1308dd4bdcdSmrg opts->x_TARGET_NO_SUM_IN_TOC = 0;
1318dd4bdcdSmrg }
1328dd4bdcdSmrg break;
1338dd4bdcdSmrg
1348dd4bdcdSmrg case OPT_mpowerpc_gpopt:
1358dd4bdcdSmrg case OPT_mpowerpc_gfxopt:
1368dd4bdcdSmrg break;
1378dd4bdcdSmrg
1388dd4bdcdSmrg case OPT_mdebug_:
1398dd4bdcdSmrg p = ASTRDUP (arg);
1408dd4bdcdSmrg opts->x_rs6000_debug = 0;
1418dd4bdcdSmrg
1428dd4bdcdSmrg while ((q = strtok (p, ",")) != NULL)
1438dd4bdcdSmrg {
1448dd4bdcdSmrg unsigned mask = 0;
1458dd4bdcdSmrg bool invert;
1468dd4bdcdSmrg
1478dd4bdcdSmrg p = NULL;
1488dd4bdcdSmrg if (*q == '!')
1498dd4bdcdSmrg {
1508dd4bdcdSmrg invert = true;
1518dd4bdcdSmrg q++;
1528dd4bdcdSmrg }
1538dd4bdcdSmrg else
1548dd4bdcdSmrg invert = false;
1558dd4bdcdSmrg
1568dd4bdcdSmrg if (! strcmp (q, "all"))
1578dd4bdcdSmrg mask = MASK_DEBUG_ALL;
1588dd4bdcdSmrg else if (! strcmp (q, "stack"))
1598dd4bdcdSmrg mask = MASK_DEBUG_STACK;
1608dd4bdcdSmrg else if (! strcmp (q, "arg"))
1618dd4bdcdSmrg mask = MASK_DEBUG_ARG;
1628dd4bdcdSmrg else if (! strcmp (q, "reg"))
1638dd4bdcdSmrg mask = MASK_DEBUG_REG;
1648dd4bdcdSmrg else if (! strcmp (q, "addr"))
1658dd4bdcdSmrg mask = MASK_DEBUG_ADDR;
1668dd4bdcdSmrg else if (! strcmp (q, "cost"))
1678dd4bdcdSmrg mask = MASK_DEBUG_COST;
1688dd4bdcdSmrg else if (! strcmp (q, "target"))
1698dd4bdcdSmrg mask = MASK_DEBUG_TARGET;
1708dd4bdcdSmrg else if (! strcmp (q, "builtin"))
1718dd4bdcdSmrg mask = MASK_DEBUG_BUILTIN;
1728dd4bdcdSmrg else
173*760c2415Smrg error_at (loc, "unknown %<-mdebug-%s%> switch", q);
1748dd4bdcdSmrg
1758dd4bdcdSmrg if (invert)
1768dd4bdcdSmrg opts->x_rs6000_debug &= ~mask;
1778dd4bdcdSmrg else
1788dd4bdcdSmrg opts->x_rs6000_debug |= mask;
1798dd4bdcdSmrg }
1808dd4bdcdSmrg break;
1818dd4bdcdSmrg
1828dd4bdcdSmrg #ifdef TARGET_USES_SYSV4_OPT
1838dd4bdcdSmrg case OPT_mrelocatable:
1848dd4bdcdSmrg if (value == 1)
1858dd4bdcdSmrg {
1868dd4bdcdSmrg opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
1878dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
1888dd4bdcdSmrg opts->x_TARGET_NO_FP_IN_TOC = 1;
1898dd4bdcdSmrg }
1908dd4bdcdSmrg break;
1918dd4bdcdSmrg
1928dd4bdcdSmrg case OPT_mrelocatable_lib:
1938dd4bdcdSmrg if (value == 1)
1948dd4bdcdSmrg {
1958dd4bdcdSmrg opts->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE
1968dd4bdcdSmrg | OPTION_MASK_MINIMAL_TOC);
1978dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE
1988dd4bdcdSmrg | OPTION_MASK_MINIMAL_TOC);
1998dd4bdcdSmrg opts->x_TARGET_NO_FP_IN_TOC = 1;
2008dd4bdcdSmrg }
2018dd4bdcdSmrg else
2028dd4bdcdSmrg {
2038dd4bdcdSmrg opts->x_rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE;
2048dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_RELOCATABLE;
2058dd4bdcdSmrg }
2068dd4bdcdSmrg break;
2078dd4bdcdSmrg #endif
2088dd4bdcdSmrg
2098dd4bdcdSmrg case OPT_mabi_altivec:
2108dd4bdcdSmrg /* Enabling the AltiVec ABI turns off the SPE ABI. */
2118dd4bdcdSmrg opts->x_rs6000_spe_abi = 0;
2128dd4bdcdSmrg break;
2138dd4bdcdSmrg
2148dd4bdcdSmrg case OPT_mabi_spe:
2158dd4bdcdSmrg opts->x_rs6000_altivec_abi = 0;
2168dd4bdcdSmrg break;
2178dd4bdcdSmrg
2188dd4bdcdSmrg case OPT_mlong_double_:
2198dd4bdcdSmrg if (value != 64 && value != 128)
2208dd4bdcdSmrg {
221*760c2415Smrg error_at (loc, "unknown switch %<-mlong-double-%s%>", arg);
2228dd4bdcdSmrg opts->x_rs6000_long_double_type_size
2238dd4bdcdSmrg = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2248dd4bdcdSmrg return false;
2258dd4bdcdSmrg }
2268dd4bdcdSmrg break;
2278dd4bdcdSmrg
2288dd4bdcdSmrg case OPT_msingle_float:
2298dd4bdcdSmrg if (!TARGET_SINGLE_FPU)
2308dd4bdcdSmrg warning_at (loc, 0,
231*760c2415Smrg "%<-msingle-float%> option equivalent to %<-mhard-float%>");
2328dd4bdcdSmrg /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
2338dd4bdcdSmrg opts->x_rs6000_double_float = 0;
2348dd4bdcdSmrg opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT;
2358dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
2368dd4bdcdSmrg break;
2378dd4bdcdSmrg
2388dd4bdcdSmrg case OPT_mdouble_float:
2398dd4bdcdSmrg /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
2408dd4bdcdSmrg opts->x_rs6000_single_float = 1;
2418dd4bdcdSmrg opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT;
2428dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
2438dd4bdcdSmrg break;
2448dd4bdcdSmrg
2458dd4bdcdSmrg case OPT_msimple_fpu:
2468dd4bdcdSmrg if (!TARGET_SINGLE_FPU)
247*760c2415Smrg warning_at (loc, 0, "%<-msimple-fpu%> option ignored");
2488dd4bdcdSmrg break;
2498dd4bdcdSmrg
2508dd4bdcdSmrg case OPT_mhard_float:
2518dd4bdcdSmrg /* -mhard_float implies -msingle-float and -mdouble-float. */
2528dd4bdcdSmrg opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1;
2538dd4bdcdSmrg break;
2548dd4bdcdSmrg
2558dd4bdcdSmrg case OPT_msoft_float:
2568dd4bdcdSmrg /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
2578dd4bdcdSmrg opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0;
2588dd4bdcdSmrg break;
2598dd4bdcdSmrg
2608dd4bdcdSmrg case OPT_mfpu_:
2618dd4bdcdSmrg fpu_type = (enum fpu_type_t) value;
2628dd4bdcdSmrg if (fpu_type != FPU_NONE)
2638dd4bdcdSmrg {
2648dd4bdcdSmrg /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on
2658dd4bdcdSmrg HARD_FLOAT. */
2668dd4bdcdSmrg opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT;
2678dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
2688dd4bdcdSmrg opts->x_rs6000_xilinx_fpu = 1;
2698dd4bdcdSmrg if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
2708dd4bdcdSmrg opts->x_rs6000_single_float = 1;
2718dd4bdcdSmrg if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
2728dd4bdcdSmrg opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1;
2738dd4bdcdSmrg if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
2748dd4bdcdSmrg opts->x_rs6000_simple_fpu = 1;
2758dd4bdcdSmrg }
2768dd4bdcdSmrg else
2778dd4bdcdSmrg {
2788dd4bdcdSmrg /* -mfpu=none is equivalent to -msoft-float. */
2798dd4bdcdSmrg opts->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
2808dd4bdcdSmrg opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
2818dd4bdcdSmrg opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0;
2828dd4bdcdSmrg }
2838dd4bdcdSmrg break;
2848dd4bdcdSmrg
2858dd4bdcdSmrg case OPT_mrecip:
2868dd4bdcdSmrg opts->x_rs6000_recip_name = (value) ? "default" : "none";
2878dd4bdcdSmrg break;
2888dd4bdcdSmrg }
2898dd4bdcdSmrg return true;
2908dd4bdcdSmrg }
2918dd4bdcdSmrg
2928dd4bdcdSmrg /* -fsplit-stack uses a field in the TCB, available with glibc-2.19.
2938dd4bdcdSmrg We also allow 2.18 because alignment padding guarantees that the
2948dd4bdcdSmrg space is available there too. */
2958dd4bdcdSmrg
2968dd4bdcdSmrg static bool
rs6000_supports_split_stack(bool report,struct gcc_options * opts ATTRIBUTE_UNUSED)2978dd4bdcdSmrg rs6000_supports_split_stack (bool report,
2988dd4bdcdSmrg struct gcc_options *opts ATTRIBUTE_UNUSED)
2998dd4bdcdSmrg {
3008dd4bdcdSmrg #ifndef TARGET_GLIBC_MAJOR
3018dd4bdcdSmrg #define TARGET_GLIBC_MAJOR 0
3028dd4bdcdSmrg #endif
3038dd4bdcdSmrg #ifndef TARGET_GLIBC_MINOR
3048dd4bdcdSmrg #define TARGET_GLIBC_MINOR 0
3058dd4bdcdSmrg #endif
3068dd4bdcdSmrg /* Note: Can't test DEFAULT_ABI here, it isn't set until later. */
3078dd4bdcdSmrg if (TARGET_GLIBC_MAJOR * 1000 + TARGET_GLIBC_MINOR >= 2018
3088dd4bdcdSmrg && TARGET_64BIT
3098dd4bdcdSmrg && TARGET_ELF)
3108dd4bdcdSmrg return true;
3118dd4bdcdSmrg
3128dd4bdcdSmrg if (report)
3138dd4bdcdSmrg error ("%<-fsplit-stack%> currently only supported on PowerPC64 GNU/Linux with glibc-2.18 or later");
3148dd4bdcdSmrg return false;
3158dd4bdcdSmrg }
3168dd4bdcdSmrg
3178dd4bdcdSmrg #undef TARGET_HANDLE_OPTION
3188dd4bdcdSmrg #define TARGET_HANDLE_OPTION rs6000_handle_option
3198dd4bdcdSmrg
3208dd4bdcdSmrg #undef TARGET_OPTION_INIT_STRUCT
3218dd4bdcdSmrg #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
3228dd4bdcdSmrg
3238dd4bdcdSmrg #undef TARGET_OPTION_DEFAULT_PARAMS
3248dd4bdcdSmrg #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
3258dd4bdcdSmrg
3268dd4bdcdSmrg #undef TARGET_OPTION_OPTIMIZATION_TABLE
3278dd4bdcdSmrg #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
3288dd4bdcdSmrg
3298dd4bdcdSmrg #undef TARGET_SUPPORTS_SPLIT_STACK
3308dd4bdcdSmrg #define TARGET_SUPPORTS_SPLIT_STACK rs6000_supports_split_stack
3318dd4bdcdSmrg
3328dd4bdcdSmrg struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
333