1 /* Common hooks for IBM RS/6000. 2 Copyright (C) 1991-2015 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 #include "params.h" 30 31 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ 32 static const struct default_options rs6000_option_optimization_table[] = 33 { 34 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, 35 { OPT_LEVELS_NONE, 0, NULL, 0 } 36 }; 37 38 /* Implement TARGET_OPTION_INIT_STRUCT. */ 39 40 static void 41 rs6000_option_init_struct (struct gcc_options *opts) 42 { 43 if (DEFAULT_ABI == ABI_DARWIN) 44 /* The Darwin libraries never set errno, so we might as well 45 avoid calling them when that's the only reason we would. */ 46 opts->x_flag_errno_math = 0; 47 48 /* Enable section anchors by default. */ 49 if (!TARGET_MACHO) 50 opts->x_flag_section_anchors = 1; 51 } 52 53 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */ 54 55 static void 56 rs6000_option_default_params (void) 57 { 58 /* Double growth factor to counter reduced min jump length. */ 59 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16); 60 } 61 62 /* If not otherwise specified by a target, make 'long double' equivalent to 63 'double'. */ 64 65 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE 66 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64 67 #endif 68 69 /* Implement TARGET_HANDLE_OPTION. */ 70 71 static bool 72 rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, 73 const struct cl_decoded_option *decoded, 74 location_t loc) 75 { 76 enum fpu_type_t fpu_type = FPU_NONE; 77 char *p, *q; 78 size_t code = decoded->opt_index; 79 const char *arg = decoded->arg; 80 int value = decoded->value; 81 82 switch (code) 83 { 84 case OPT_mfull_toc: 85 opts->x_rs6000_isa_flags &= ~OPTION_MASK_MINIMAL_TOC; 86 opts->x_TARGET_NO_FP_IN_TOC = 0; 87 opts->x_TARGET_NO_SUM_IN_TOC = 0; 88 opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 89 #ifdef TARGET_USES_SYSV4_OPT 90 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be 91 just the same as -mminimal-toc. */ 92 opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 93 opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 94 #endif 95 break; 96 97 #ifdef TARGET_USES_SYSV4_OPT 98 case OPT_mtoc: 99 /* Make -mtoc behave like -mminimal-toc. */ 100 opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 101 opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 102 break; 103 #endif 104 105 #ifdef TARGET_USES_AIX64_OPT 106 case OPT_maix64: 107 #else 108 case OPT_m64: 109 #endif 110 opts->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64; 111 opts->x_rs6000_isa_flags |= (~opts_set->x_rs6000_isa_flags 112 & OPTION_MASK_PPC_GFXOPT); 113 opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64; 114 break; 115 116 #ifdef TARGET_USES_AIX64_OPT 117 case OPT_maix32: 118 #else 119 case OPT_m32: 120 #endif 121 opts->x_rs6000_isa_flags &= ~OPTION_MASK_POWERPC64; 122 opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64; 123 break; 124 125 case OPT_mminimal_toc: 126 if (value == 1) 127 { 128 opts->x_TARGET_NO_FP_IN_TOC = 0; 129 opts->x_TARGET_NO_SUM_IN_TOC = 0; 130 } 131 break; 132 133 case OPT_mpowerpc_gpopt: 134 case OPT_mpowerpc_gfxopt: 135 break; 136 137 case OPT_mdebug_: 138 p = ASTRDUP (arg); 139 opts->x_rs6000_debug = 0; 140 141 while ((q = strtok (p, ",")) != NULL) 142 { 143 unsigned mask = 0; 144 bool invert; 145 146 p = NULL; 147 if (*q == '!') 148 { 149 invert = true; 150 q++; 151 } 152 else 153 invert = false; 154 155 if (! strcmp (q, "all")) 156 mask = MASK_DEBUG_ALL; 157 else if (! strcmp (q, "stack")) 158 mask = MASK_DEBUG_STACK; 159 else if (! strcmp (q, "arg")) 160 mask = MASK_DEBUG_ARG; 161 else if (! strcmp (q, "reg")) 162 mask = MASK_DEBUG_REG; 163 else if (! strcmp (q, "addr")) 164 mask = MASK_DEBUG_ADDR; 165 else if (! strcmp (q, "cost")) 166 mask = MASK_DEBUG_COST; 167 else if (! strcmp (q, "target")) 168 mask = MASK_DEBUG_TARGET; 169 else if (! strcmp (q, "builtin")) 170 mask = MASK_DEBUG_BUILTIN; 171 else 172 error_at (loc, "unknown -mdebug-%s switch", q); 173 174 if (invert) 175 opts->x_rs6000_debug &= ~mask; 176 else 177 opts->x_rs6000_debug |= mask; 178 } 179 break; 180 181 #ifdef TARGET_USES_SYSV4_OPT 182 case OPT_mrelocatable: 183 if (value == 1) 184 { 185 opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 186 opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; 187 opts->x_TARGET_NO_FP_IN_TOC = 1; 188 } 189 break; 190 191 case OPT_mrelocatable_lib: 192 if (value == 1) 193 { 194 opts->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE 195 | OPTION_MASK_MINIMAL_TOC); 196 opts_set->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE 197 | OPTION_MASK_MINIMAL_TOC); 198 opts->x_TARGET_NO_FP_IN_TOC = 1; 199 } 200 else 201 { 202 opts->x_rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; 203 opts_set->x_rs6000_isa_flags |= OPTION_MASK_RELOCATABLE; 204 } 205 break; 206 #endif 207 208 case OPT_mabi_altivec: 209 /* Enabling the AltiVec ABI turns off the SPE ABI. */ 210 opts->x_rs6000_spe_abi = 0; 211 break; 212 213 case OPT_mabi_spe: 214 opts->x_rs6000_altivec_abi = 0; 215 break; 216 217 case OPT_mlong_double_: 218 if (value != 64 && value != 128) 219 { 220 error_at (loc, "unknown switch -mlong-double-%s", arg); 221 opts->x_rs6000_long_double_type_size 222 = RS6000_DEFAULT_LONG_DOUBLE_SIZE; 223 return false; 224 } 225 break; 226 227 case OPT_msingle_float: 228 if (!TARGET_SINGLE_FPU) 229 warning_at (loc, 0, 230 "-msingle-float option equivalent to -mhard-float"); 231 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */ 232 opts->x_rs6000_double_float = 0; 233 opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT; 234 opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; 235 break; 236 237 case OPT_mdouble_float: 238 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */ 239 opts->x_rs6000_single_float = 1; 240 opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT; 241 opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; 242 break; 243 244 case OPT_msimple_fpu: 245 if (!TARGET_SINGLE_FPU) 246 warning_at (loc, 0, "-msimple-fpu option ignored"); 247 break; 248 249 case OPT_mhard_float: 250 /* -mhard_float implies -msingle-float and -mdouble-float. */ 251 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; 252 break; 253 254 case OPT_msoft_float: 255 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */ 256 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; 257 break; 258 259 case OPT_mfpu_: 260 fpu_type = (enum fpu_type_t) value; 261 if (fpu_type != FPU_NONE) 262 { 263 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on 264 HARD_FLOAT. */ 265 opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT; 266 opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; 267 opts->x_rs6000_xilinx_fpu = 1; 268 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL) 269 opts->x_rs6000_single_float = 1; 270 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL) 271 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; 272 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE) 273 opts->x_rs6000_simple_fpu = 1; 274 } 275 else 276 { 277 /* -mfpu=none is equivalent to -msoft-float. */ 278 opts->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; 279 opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; 280 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; 281 } 282 break; 283 284 case OPT_mrecip: 285 opts->x_rs6000_recip_name = (value) ? "default" : "none"; 286 break; 287 } 288 return true; 289 } 290 291 #undef TARGET_HANDLE_OPTION 292 #define TARGET_HANDLE_OPTION rs6000_handle_option 293 294 #undef TARGET_OPTION_INIT_STRUCT 295 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct 296 297 #undef TARGET_OPTION_DEFAULT_PARAMS 298 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params 299 300 #undef TARGET_OPTION_OPTIMIZATION_TABLE 301 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table 302 303 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; 304