1/* Common hooks for IBM RS/6000. 2 Copyright (C) 1991-2022 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#include "config.h" 21#include "system.h" 22#include "coretypes.h" 23#include "diagnostic-core.h" 24#include "tm.h" 25#include "common/common-target.h" 26#include "common/common-target-def.h" 27#include "opts.h" 28#include "flags.h" 29 30/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ 31static const struct default_options rs6000_option_optimization_table[] = 32 { 33 /* Split multi-word types early. */ 34 { OPT_LEVELS_ALL, OPT_fsplit_wide_types_early, NULL, 1 }, 35 /* Enable -fsched-pressure for first pass instruction scheduling. */ 36 { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 }, 37 /* Enable -munroll-only-small-loops with -funroll-loops to unroll small 38 loops at -O2 and above by default. */ 39 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_funroll_loops, NULL, 1 }, 40 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_munroll_only_small_loops, NULL, 1 }, 41 42 /* -frename-registers leads to non-optimal codegen and performance 43 on rs6000, turn it off by default. */ 44 { OPT_LEVELS_ALL, OPT_frename_registers, NULL, 0 }, 45 46 /* Double growth factor to counter reduced min jump length. */ 47 { OPT_LEVELS_ALL, OPT__param_max_grow_copy_bb_insns_, NULL, 16 }, 48 { OPT_LEVELS_NONE, 0, NULL, 0 } 49 }; 50 51/* Implement TARGET_OPTION_INIT_STRUCT. */ 52 53static void 54rs6000_option_init_struct (struct gcc_options *opts) 55{ 56 if (DEFAULT_ABI == ABI_DARWIN) 57 /* The Darwin libraries never set errno, so we might as well 58 avoid calling them when that's the only reason we would. */ 59 opts->x_flag_errno_math = 0; 60 61 /* Enable section anchors by default. */ 62 if (!TARGET_MACHO) 63 opts->x_flag_section_anchors = 1; 64 65 /* By default, always emit DWARF-2 unwind info. This allows debugging 66 without maintaining a stack frame back-chain. It also allows the 67 debugger to find out where on-entry register values are stored at any 68 point in a function, without having to analyze the executable code (which 69 isn't even possible to do in the general case). */ 70#ifdef OBJECT_FORMAT_ELF 71 opts->x_flag_asynchronous_unwind_tables = 1; 72#endif 73} 74 75/* If not otherwise specified by a target, make 'long double' equivalent to 76 'double'. */ 77 78#ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE 79#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64 80#endif 81 82/* Implement TARGET_HANDLE_OPTION. */ 83 84static bool 85rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, 86 const struct cl_decoded_option *decoded, 87 location_t loc) 88{ 89 char *p, *q; 90 size_t code = decoded->opt_index; 91 const char *arg = decoded->arg; 92 int value = decoded->value; 93 94 switch (code) 95 { 96 case OPT_mfull_toc: 97 opts->x_rs6000_isa_flags &= ~OPTION_MASK_MINIMAL_TOC; 98 opts->x_TARGET_NO_FP_IN_TOC = 0; 99 opts->x_TARGET_NO_SUM_IN_TOC = 0; 100 opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 101#ifdef TARGET_USES_SYSV4_OPT 102 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be 103 just the same as -mminimal-toc. */ 104 opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 105 opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 106#endif 107 break; 108 109#ifdef TARGET_USES_SYSV4_OPT 110 case OPT_mtoc: 111 /* Make -mtoc behave like -mminimal-toc. */ 112 opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 113 opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 114 break; 115#endif 116 117#ifdef TARGET_USES_AIX64_OPT 118 case OPT_maix64: 119#else 120 case OPT_m64: 121#endif 122 opts->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64; 123 opts->x_rs6000_isa_flags |= (~opts_set->x_rs6000_isa_flags 124 & OPTION_MASK_PPC_GFXOPT); 125 opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64; 126 break; 127 128#ifdef TARGET_USES_AIX64_OPT 129 case OPT_maix32: 130#else 131 case OPT_m32: 132#endif 133 opts->x_rs6000_isa_flags &= ~OPTION_MASK_POWERPC64; 134 opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64; 135 break; 136 137 case OPT_mminimal_toc: 138 if (value == 1) 139 { 140 opts->x_TARGET_NO_FP_IN_TOC = 0; 141 opts->x_TARGET_NO_SUM_IN_TOC = 0; 142 } 143 break; 144 145 case OPT_mpowerpc_gpopt: 146 case OPT_mpowerpc_gfxopt: 147 break; 148 149 case OPT_mdebug_: 150 p = ASTRDUP (arg); 151 opts->x_rs6000_debug = 0; 152 153 while ((q = strtok (p, ",")) != NULL) 154 { 155 unsigned mask = 0; 156 bool invert; 157 158 p = NULL; 159 if (*q == '!') 160 { 161 invert = true; 162 q++; 163 } 164 else 165 invert = false; 166 167 if (! strcmp (q, "all")) 168 mask = MASK_DEBUG_ALL; 169 else if (! strcmp (q, "stack")) 170 mask = MASK_DEBUG_STACK; 171 else if (! strcmp (q, "arg")) 172 mask = MASK_DEBUG_ARG; 173 else if (! strcmp (q, "reg")) 174 mask = MASK_DEBUG_REG; 175 else if (! strcmp (q, "addr")) 176 mask = MASK_DEBUG_ADDR; 177 else if (! strcmp (q, "cost")) 178 mask = MASK_DEBUG_COST; 179 else if (! strcmp (q, "target")) 180 mask = MASK_DEBUG_TARGET; 181 else if (! strcmp (q, "builtin")) 182 mask = MASK_DEBUG_BUILTIN; 183 else 184 error_at (loc, "unknown %<-mdebug-%s%> switch", q); 185 186 if (invert) 187 opts->x_rs6000_debug &= ~mask; 188 else 189 opts->x_rs6000_debug |= mask; 190 } 191 break; 192 193#ifdef TARGET_USES_SYSV4_OPT 194 case OPT_mrelocatable: 195 if (value == 1) 196 { 197 opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 198 opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 199 opts->x_TARGET_NO_FP_IN_TOC = 1; 200 } 201 break; 202 203 case OPT_mrelocatable_lib: 204 if (value == 1) 205 { 206 opts->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE 207 | OPTION_MASK_MINIMAL_TOC); 208 opts_set->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE 209 | OPTION_MASK_MINIMAL_TOC); 210 opts->x_TARGET_NO_FP_IN_TOC = 1; 211 } 212 else 213 { 214 opts->x_rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; 215 opts_set->x_rs6000_isa_flags |= OPTION_MASK_RELOCATABLE; 216 } 217 break; 218#endif 219 220 case OPT_mlong_double_: 221 if (value != 64 && value != 128) 222 { 223 error_at (loc, "unknown switch %<-mlong-double-%s%>", arg); 224 opts->x_rs6000_long_double_type_size 225 = RS6000_DEFAULT_LONG_DOUBLE_SIZE; 226 return false; 227 } 228 break; 229 230 case OPT_mabi_ibmlongdouble: 231 case OPT_mabi_ieeelongdouble: 232 if (opts->x_rs6000_long_double_type_size == 64) 233 { 234 error_at (loc, "option %<%s%> requires %<-mlong-double-128%>", 235 decoded->orig_option_with_args_text); 236 return true; 237 } 238 break; 239 240 case OPT_mrecip: 241 opts->x_rs6000_recip_name = (value) ? "default" : "none"; 242 break; 243 } 244 return true; 245} 246 247/* -fsplit-stack uses a field in the TCB, available with glibc-2.19. 248 We also allow 2.18 because alignment padding guarantees that the 249 space is available there too. */ 250 251static bool 252rs6000_supports_split_stack (bool report, 253 struct gcc_options *opts ATTRIBUTE_UNUSED) 254{ 255#ifndef TARGET_GLIBC_MAJOR 256#define TARGET_GLIBC_MAJOR 0 257#endif 258#ifndef TARGET_GLIBC_MINOR 259#define TARGET_GLIBC_MINOR 0 260#endif 261 /* Note: Can't test DEFAULT_ABI here, it isn't set until later. */ 262 if (TARGET_GLIBC_MAJOR * 1000 + TARGET_GLIBC_MINOR >= 2018 263 && TARGET_64BIT 264 && TARGET_ELF) 265 return true; 266 267 if (report) 268 error ("%<-fsplit-stack%> currently only supported on PowerPC64 GNU/Linux with glibc-2.18 or later"); 269 return false; 270} 271 272#undef TARGET_HANDLE_OPTION 273#define TARGET_HANDLE_OPTION rs6000_handle_option 274 275#undef TARGET_OPTION_INIT_STRUCT 276#define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct 277 278#undef TARGET_OPTION_OPTIMIZATION_TABLE 279#define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table 280 281#undef TARGET_SUPPORTS_SPLIT_STACK 282#define TARGET_SUPPORTS_SPLIT_STACK rs6000_supports_split_stack 283 284struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; 285