URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [common/] [config/] [rs6000/] [rs6000-common.c] - Rev 708
Compare with Previous | Blame | View Log
/* Common hooks for IBM RS/6000. Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. 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. 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 GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" #include "system.h" #include "coretypes.h" #include "diagnostic-core.h" #include "tm.h" #include "common/common-target.h" #include "common/common-target-def.h" #include "opts.h" #include "flags.h" #include "params.h" /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ static const struct default_options rs6000_option_optimization_table[] = { { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, { OPT_LEVELS_NONE, 0, NULL, 0 } }; /* Implement TARGET_OPTION_INIT_STRUCT. */ static void rs6000_option_init_struct (struct gcc_options *opts) { if (DEFAULT_ABI == ABI_DARWIN) /* The Darwin libraries never set errno, so we might as well avoid calling them when that's the only reason we would. */ opts->x_flag_errno_math = 0; /* Enable section anchors by default. */ if (!TARGET_MACHO) opts->x_flag_section_anchors = 1; } /* Implement TARGET_OPTION_DEFAULT_PARAMS. */ static void rs6000_option_default_params (void) { /* Double growth factor to counter reduced min jump length. */ set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16); } /* If not otherwise specified by a target, make 'long double' equivalent to 'double'. */ #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64 #endif /* Implement TARGET_HANDLE_OPTION. */ static bool rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, const struct cl_decoded_option *decoded, location_t loc) { enum fpu_type_t fpu_type = FPU_NONE; char *p, *q; size_t code = decoded->opt_index; const char *arg = decoded->arg; int value = decoded->value; switch (code) { case OPT_mno_power: opts->x_target_flags &= ~(MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING); opts_set->x_target_flags |= (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING); break; case OPT_mno_powerpc: opts->x_target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT | MASK_PPC_GFXOPT | MASK_POWERPC64); opts_set->x_target_flags |= (MASK_POWERPC | MASK_PPC_GPOPT | MASK_PPC_GFXOPT | MASK_POWERPC64); break; case OPT_mfull_toc: opts->x_target_flags &= ~MASK_MINIMAL_TOC; opts->x_TARGET_NO_FP_IN_TOC = 0; opts->x_TARGET_NO_SUM_IN_TOC = 0; opts_set->x_target_flags |= MASK_MINIMAL_TOC; #ifdef TARGET_USES_SYSV4_OPT /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be just the same as -mminimal-toc. */ opts->x_target_flags |= MASK_MINIMAL_TOC; opts_set->x_target_flags |= MASK_MINIMAL_TOC; #endif break; #ifdef TARGET_USES_SYSV4_OPT case OPT_mtoc: /* Make -mtoc behave like -mminimal-toc. */ opts->x_target_flags |= MASK_MINIMAL_TOC; opts_set->x_target_flags |= MASK_MINIMAL_TOC; break; #endif #ifdef TARGET_USES_AIX64_OPT case OPT_maix64: #else case OPT_m64: #endif opts->x_target_flags |= MASK_POWERPC64 | MASK_POWERPC; opts->x_target_flags |= ~opts_set->x_target_flags & MASK_PPC_GFXOPT; opts_set->x_target_flags |= MASK_POWERPC64 | MASK_POWERPC; break; #ifdef TARGET_USES_AIX64_OPT case OPT_maix32: #else case OPT_m32: #endif opts->x_target_flags &= ~MASK_POWERPC64; opts_set->x_target_flags |= MASK_POWERPC64; break; case OPT_mminimal_toc: if (value == 1) { opts->x_TARGET_NO_FP_IN_TOC = 0; opts->x_TARGET_NO_SUM_IN_TOC = 0; } break; case OPT_mpower: if (value == 1) { opts->x_target_flags |= (MASK_MULTIPLE | MASK_STRING); opts_set->x_target_flags |= (MASK_MULTIPLE | MASK_STRING); } break; case OPT_mpower2: if (value == 1) { opts->x_target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING); opts_set->x_target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING); } break; case OPT_mpowerpc_gpopt: case OPT_mpowerpc_gfxopt: if (value == 1) { opts->x_target_flags |= MASK_POWERPC; opts_set->x_target_flags |= MASK_POWERPC; } break; case OPT_mdebug_: p = ASTRDUP (arg); opts->x_rs6000_debug = 0; while ((q = strtok (p, ",")) != NULL) { unsigned mask = 0; bool invert; p = NULL; if (*q == '!') { invert = true; q++; } else invert = false; if (! strcmp (q, "all")) mask = MASK_DEBUG_ALL; else if (! strcmp (q, "stack")) mask = MASK_DEBUG_STACK; else if (! strcmp (q, "arg")) mask = MASK_DEBUG_ARG; else if (! strcmp (q, "reg")) mask = MASK_DEBUG_REG; else if (! strcmp (q, "addr")) mask = MASK_DEBUG_ADDR; else if (! strcmp (q, "cost")) mask = MASK_DEBUG_COST; else if (! strcmp (q, "target")) mask = MASK_DEBUG_TARGET; else if (! strcmp (q, "builtin")) mask = MASK_DEBUG_BUILTIN; else error_at (loc, "unknown -mdebug-%s switch", q); if (invert) opts->x_rs6000_debug &= ~mask; else opts->x_rs6000_debug |= mask; } break; #ifdef TARGET_USES_SYSV4_OPT case OPT_mrelocatable: if (value == 1) { opts->x_target_flags |= MASK_MINIMAL_TOC; opts_set->x_target_flags |= MASK_MINIMAL_TOC; opts->x_TARGET_NO_FP_IN_TOC = 1; } break; case OPT_mrelocatable_lib: if (value == 1) { opts->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC; opts_set->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC; opts->x_TARGET_NO_FP_IN_TOC = 1; } else { opts->x_target_flags &= ~MASK_RELOCATABLE; opts_set->x_target_flags |= MASK_RELOCATABLE; } break; #endif case OPT_mabi_altivec: /* Enabling the AltiVec ABI turns off the SPE ABI. */ opts->x_rs6000_spe_abi = 0; break; case OPT_mabi_spe: opts->x_rs6000_altivec_abi = 0; break; case OPT_mlong_double_: if (value != 64 && value != 128) { error_at (loc, "unknown switch -mlong-double-%s", arg); opts->x_rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE; return false; } break; case OPT_msingle_float: if (!TARGET_SINGLE_FPU) warning_at (loc, 0, "-msingle-float option equivalent to -mhard-float"); /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */ opts->x_rs6000_double_float = 0; opts->x_target_flags &= ~MASK_SOFT_FLOAT; opts_set->x_target_flags |= MASK_SOFT_FLOAT; break; case OPT_mdouble_float: /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */ opts->x_rs6000_single_float = 1; opts->x_target_flags &= ~MASK_SOFT_FLOAT; opts_set->x_target_flags |= MASK_SOFT_FLOAT; break; case OPT_msimple_fpu: if (!TARGET_SINGLE_FPU) warning_at (loc, 0, "-msimple-fpu option ignored"); break; case OPT_mhard_float: /* -mhard_float implies -msingle-float and -mdouble-float. */ opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; break; case OPT_msoft_float: /* -msoft_float implies -mnosingle-float and -mnodouble-float. */ opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; break; case OPT_mfpu_: fpu_type = (enum fpu_type_t) value; if (fpu_type != FPU_NONE) { /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */ opts->x_target_flags &= ~MASK_SOFT_FLOAT; opts_set->x_target_flags |= MASK_SOFT_FLOAT; opts->x_rs6000_xilinx_fpu = 1; if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL) opts->x_rs6000_single_float = 1; if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL) opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE) opts->x_rs6000_simple_fpu = 1; } else { /* -mfpu=none is equivalent to -msoft-float. */ opts->x_target_flags |= MASK_SOFT_FLOAT; opts_set->x_target_flags |= MASK_SOFT_FLOAT; opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; } break; case OPT_mrecip: opts->x_rs6000_recip_name = (value) ? "default" : "none"; break; } return true; } #undef TARGET_HANDLE_OPTION #define TARGET_HANDLE_OPTION rs6000_handle_option #undef TARGET_OPTION_INIT_STRUCT #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct #undef TARGET_OPTION_DEFAULT_PARAMS #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params #undef TARGET_OPTION_OPTIMIZATION_TABLE #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table #undef TARGET_DEFAULT_TARGET_FLAGS #define TARGET_DEFAULT_TARGET_FLAGS \ (TARGET_DEFAULT) struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;