xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/common/config/powerpcspe/powerpcspe-common.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1cef8759bSmrg /* Common hooks for IBM RS/6000.
2*627f7eb2Smrg    Copyright (C) 1991-2019 Free Software Foundation, Inc.
3cef8759bSmrg 
4cef8759bSmrg    This file is part of GCC.
5cef8759bSmrg 
6cef8759bSmrg    GCC is free software; you can redistribute it and/or modify it
7cef8759bSmrg    under the terms of the GNU General Public License as published
8cef8759bSmrg    by the Free Software Foundation; either version 3, or (at your
9cef8759bSmrg    option) any later version.
10cef8759bSmrg 
11cef8759bSmrg    GCC is distributed in the hope that it will be useful, but WITHOUT
12cef8759bSmrg    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13cef8759bSmrg    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14cef8759bSmrg    License for more details.
15cef8759bSmrg 
16cef8759bSmrg    You should have received a copy of the GNU General Public License
17cef8759bSmrg    along with GCC; see the file COPYING3.  If not see
18cef8759bSmrg    <http://www.gnu.org/licenses/>.  */
19cef8759bSmrg 
20cef8759bSmrg #include "config.h"
21cef8759bSmrg #include "system.h"
22cef8759bSmrg #include "coretypes.h"
23cef8759bSmrg #include "diagnostic-core.h"
24cef8759bSmrg #include "tm.h"
25cef8759bSmrg #include "common/common-target.h"
26cef8759bSmrg #include "common/common-target-def.h"
27cef8759bSmrg #include "opts.h"
28cef8759bSmrg #include "flags.h"
29cef8759bSmrg #include "params.h"
30cef8759bSmrg 
31cef8759bSmrg /* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
32cef8759bSmrg static const struct default_options rs6000_option_optimization_table[] =
33cef8759bSmrg   {
34cef8759bSmrg     /* Enable -fsched-pressure for first pass instruction scheduling.  */
35cef8759bSmrg     { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
36cef8759bSmrg     { OPT_LEVELS_NONE, 0, NULL, 0 }
37cef8759bSmrg   };
38cef8759bSmrg 
39cef8759bSmrg /* Implement TARGET_OPTION_INIT_STRUCT.  */
40cef8759bSmrg 
41cef8759bSmrg static void
rs6000_option_init_struct(struct gcc_options * opts)42cef8759bSmrg rs6000_option_init_struct (struct gcc_options *opts)
43cef8759bSmrg {
44cef8759bSmrg   if (DEFAULT_ABI == ABI_DARWIN)
45cef8759bSmrg     /* The Darwin libraries never set errno, so we might as well
46cef8759bSmrg        avoid calling them when that's the only reason we would.  */
47cef8759bSmrg     opts->x_flag_errno_math = 0;
48cef8759bSmrg 
49cef8759bSmrg   /* Enable section anchors by default.  */
50cef8759bSmrg   if (!TARGET_MACHO)
51cef8759bSmrg     opts->x_flag_section_anchors = 1;
52cef8759bSmrg }
53cef8759bSmrg 
54cef8759bSmrg /* Implement TARGET_OPTION_DEFAULT_PARAMS.  */
55cef8759bSmrg 
56cef8759bSmrg static void
rs6000_option_default_params(void)57cef8759bSmrg rs6000_option_default_params (void)
58cef8759bSmrg {
59cef8759bSmrg   /* Double growth factor to counter reduced min jump length.  */
60cef8759bSmrg   set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
61cef8759bSmrg }
62cef8759bSmrg 
63cef8759bSmrg /* If not otherwise specified by a target, make 'long double' equivalent to
64cef8759bSmrg    'double'.  */
65cef8759bSmrg 
66cef8759bSmrg #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
67cef8759bSmrg #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
68cef8759bSmrg #endif
69cef8759bSmrg 
70cef8759bSmrg /* Implement TARGET_HANDLE_OPTION.  */
71cef8759bSmrg 
72cef8759bSmrg static bool
rs6000_handle_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct cl_decoded_option * decoded,location_t loc)73cef8759bSmrg rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
74cef8759bSmrg 		      const struct cl_decoded_option *decoded,
75cef8759bSmrg 		      location_t loc)
76cef8759bSmrg {
77cef8759bSmrg   enum fpu_type_t fpu_type = FPU_NONE;
78cef8759bSmrg   char *p, *q;
79cef8759bSmrg   size_t code = decoded->opt_index;
80cef8759bSmrg   const char *arg = decoded->arg;
81cef8759bSmrg   int value = decoded->value;
82cef8759bSmrg 
83cef8759bSmrg   switch (code)
84cef8759bSmrg     {
85cef8759bSmrg     case OPT_mfull_toc:
86cef8759bSmrg       opts->x_rs6000_isa_flags &= ~OPTION_MASK_MINIMAL_TOC;
87cef8759bSmrg       opts->x_TARGET_NO_FP_IN_TOC = 0;
88cef8759bSmrg       opts->x_TARGET_NO_SUM_IN_TOC = 0;
89cef8759bSmrg       opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
90cef8759bSmrg #ifdef TARGET_USES_SYSV4_OPT
91cef8759bSmrg       /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
92cef8759bSmrg 	 just the same as -mminimal-toc.  */
93cef8759bSmrg       opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
94cef8759bSmrg       opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
95cef8759bSmrg #endif
96cef8759bSmrg       break;
97cef8759bSmrg 
98cef8759bSmrg #ifdef TARGET_USES_SYSV4_OPT
99cef8759bSmrg     case OPT_mtoc:
100cef8759bSmrg       /* Make -mtoc behave like -mminimal-toc.  */
101cef8759bSmrg       opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
102cef8759bSmrg       opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
103cef8759bSmrg       break;
104cef8759bSmrg #endif
105cef8759bSmrg 
106cef8759bSmrg #ifdef TARGET_USES_AIX64_OPT
107cef8759bSmrg     case OPT_maix64:
108cef8759bSmrg #else
109cef8759bSmrg     case OPT_m64:
110cef8759bSmrg #endif
111cef8759bSmrg       opts->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64;
112cef8759bSmrg       opts->x_rs6000_isa_flags |= (~opts_set->x_rs6000_isa_flags
113cef8759bSmrg 				   & OPTION_MASK_PPC_GFXOPT);
114cef8759bSmrg       opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64;
115cef8759bSmrg       break;
116cef8759bSmrg 
117cef8759bSmrg #ifdef TARGET_USES_AIX64_OPT
118cef8759bSmrg     case OPT_maix32:
119cef8759bSmrg #else
120cef8759bSmrg     case OPT_m32:
121cef8759bSmrg #endif
122cef8759bSmrg       opts->x_rs6000_isa_flags &= ~OPTION_MASK_POWERPC64;
123cef8759bSmrg       opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64;
124cef8759bSmrg       break;
125cef8759bSmrg 
126cef8759bSmrg     case OPT_mminimal_toc:
127cef8759bSmrg       if (value == 1)
128cef8759bSmrg 	{
129cef8759bSmrg 	  opts->x_TARGET_NO_FP_IN_TOC = 0;
130cef8759bSmrg 	  opts->x_TARGET_NO_SUM_IN_TOC = 0;
131cef8759bSmrg 	}
132cef8759bSmrg       break;
133cef8759bSmrg 
134cef8759bSmrg     case OPT_mpowerpc_gpopt:
135cef8759bSmrg     case OPT_mpowerpc_gfxopt:
136cef8759bSmrg       break;
137cef8759bSmrg 
138cef8759bSmrg     case OPT_mdebug_:
139cef8759bSmrg       p = ASTRDUP (arg);
140cef8759bSmrg       opts->x_rs6000_debug = 0;
141cef8759bSmrg 
142cef8759bSmrg       while ((q = strtok (p, ",")) != NULL)
143cef8759bSmrg 	{
144cef8759bSmrg 	  unsigned mask = 0;
145cef8759bSmrg 	  bool invert;
146cef8759bSmrg 
147cef8759bSmrg 	  p = NULL;
148cef8759bSmrg 	  if (*q == '!')
149cef8759bSmrg 	    {
150cef8759bSmrg 	      invert = true;
151cef8759bSmrg 	      q++;
152cef8759bSmrg 	    }
153cef8759bSmrg 	  else
154cef8759bSmrg 	    invert = false;
155cef8759bSmrg 
156cef8759bSmrg 	  if (! strcmp (q, "all"))
157cef8759bSmrg 	    mask = MASK_DEBUG_ALL;
158cef8759bSmrg 	  else if (! strcmp (q, "stack"))
159cef8759bSmrg 	    mask = MASK_DEBUG_STACK;
160cef8759bSmrg 	  else if (! strcmp (q, "arg"))
161cef8759bSmrg 	    mask = MASK_DEBUG_ARG;
162cef8759bSmrg 	  else if (! strcmp (q, "reg"))
163cef8759bSmrg 	    mask = MASK_DEBUG_REG;
164cef8759bSmrg 	  else if (! strcmp (q, "addr"))
165cef8759bSmrg 	    mask = MASK_DEBUG_ADDR;
166cef8759bSmrg 	  else if (! strcmp (q, "cost"))
167cef8759bSmrg 	    mask = MASK_DEBUG_COST;
168cef8759bSmrg 	  else if (! strcmp (q, "target"))
169cef8759bSmrg 	    mask = MASK_DEBUG_TARGET;
170cef8759bSmrg 	  else if (! strcmp (q, "builtin"))
171cef8759bSmrg 	    mask = MASK_DEBUG_BUILTIN;
172cef8759bSmrg 	  else
173*627f7eb2Smrg 	    error_at (loc, "unknown %<-mdebug-%s%> switch", q);
174cef8759bSmrg 
175cef8759bSmrg 	  if (invert)
176cef8759bSmrg 	    opts->x_rs6000_debug &= ~mask;
177cef8759bSmrg 	  else
178cef8759bSmrg 	    opts->x_rs6000_debug |= mask;
179cef8759bSmrg 	}
180cef8759bSmrg       break;
181cef8759bSmrg 
182cef8759bSmrg #ifdef TARGET_USES_SYSV4_OPT
183cef8759bSmrg     case OPT_mrelocatable:
184cef8759bSmrg       if (value == 1)
185cef8759bSmrg 	{
186cef8759bSmrg 	  opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
187cef8759bSmrg 	  opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
188cef8759bSmrg 	  opts->x_TARGET_NO_FP_IN_TOC = 1;
189cef8759bSmrg 	}
190cef8759bSmrg       break;
191cef8759bSmrg 
192cef8759bSmrg     case OPT_mrelocatable_lib:
193cef8759bSmrg       if (value == 1)
194cef8759bSmrg 	{
195cef8759bSmrg 	  opts->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE
196cef8759bSmrg 				       | OPTION_MASK_MINIMAL_TOC);
197cef8759bSmrg 	  opts_set->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE
198cef8759bSmrg 					   | OPTION_MASK_MINIMAL_TOC);
199cef8759bSmrg 	  opts->x_TARGET_NO_FP_IN_TOC = 1;
200cef8759bSmrg 	}
201cef8759bSmrg       else
202cef8759bSmrg 	{
203cef8759bSmrg 	  opts->x_rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE;
204cef8759bSmrg 	  opts_set->x_rs6000_isa_flags |= OPTION_MASK_RELOCATABLE;
205cef8759bSmrg 	}
206cef8759bSmrg       break;
207cef8759bSmrg #endif
208cef8759bSmrg 
209cef8759bSmrg     case OPT_mabi_altivec:
210cef8759bSmrg       /* Enabling the AltiVec ABI turns off the SPE ABI.  */
211cef8759bSmrg       opts->x_rs6000_spe_abi = 0;
212cef8759bSmrg       break;
213cef8759bSmrg 
214cef8759bSmrg     case OPT_mabi_spe:
215cef8759bSmrg       opts->x_rs6000_altivec_abi = 0;
216cef8759bSmrg       break;
217cef8759bSmrg 
218cef8759bSmrg     case OPT_mlong_double_:
219cef8759bSmrg       if (value != 64 && value != 128)
220cef8759bSmrg 	{
221*627f7eb2Smrg 	  error_at (loc, "unknown switch %<-mlong-double-%s%>", arg);
222cef8759bSmrg 	  opts->x_rs6000_long_double_type_size
223cef8759bSmrg 	    = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
224cef8759bSmrg 	  return false;
225cef8759bSmrg 	}
226cef8759bSmrg       break;
227cef8759bSmrg 
228cef8759bSmrg     case OPT_msingle_float:
229cef8759bSmrg       if (!TARGET_SINGLE_FPU)
230cef8759bSmrg 	warning_at (loc, 0,
231*627f7eb2Smrg 		    "%<-msingle-float%> option equivalent to %<-mhard-float%>");
232cef8759bSmrg       /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
233cef8759bSmrg       opts->x_rs6000_double_float = 0;
234cef8759bSmrg       opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT;
235cef8759bSmrg       opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
236cef8759bSmrg       break;
237cef8759bSmrg 
238cef8759bSmrg     case OPT_mdouble_float:
239cef8759bSmrg       /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
240cef8759bSmrg       opts->x_rs6000_single_float = 1;
241cef8759bSmrg       opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT;
242cef8759bSmrg       opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
243cef8759bSmrg       break;
244cef8759bSmrg 
245cef8759bSmrg     case OPT_msimple_fpu:
246cef8759bSmrg       if (!TARGET_SINGLE_FPU)
247*627f7eb2Smrg 	warning_at (loc, 0, "%<-msimple-fpu%> option ignored");
248cef8759bSmrg       break;
249cef8759bSmrg 
250cef8759bSmrg     case OPT_mhard_float:
251cef8759bSmrg       /* -mhard_float implies -msingle-float and -mdouble-float. */
252cef8759bSmrg       opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1;
253cef8759bSmrg       break;
254cef8759bSmrg 
255cef8759bSmrg     case OPT_msoft_float:
256cef8759bSmrg       /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
257cef8759bSmrg       opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0;
258cef8759bSmrg       break;
259cef8759bSmrg 
260cef8759bSmrg     case OPT_mfpu_:
261cef8759bSmrg       fpu_type = (enum fpu_type_t) value;
262cef8759bSmrg       if (fpu_type != FPU_NONE)
263cef8759bSmrg 	{
264cef8759bSmrg 	  /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on
265cef8759bSmrg 	     HARD_FLOAT. */
266cef8759bSmrg 	  opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT;
267cef8759bSmrg 	  opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
268cef8759bSmrg 	  opts->x_rs6000_xilinx_fpu = 1;
269cef8759bSmrg 	  if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
270cef8759bSmrg 	    opts->x_rs6000_single_float = 1;
271cef8759bSmrg 	  if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
272cef8759bSmrg 	    opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1;
273cef8759bSmrg 	  if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
274cef8759bSmrg 	    opts->x_rs6000_simple_fpu = 1;
275cef8759bSmrg 	}
276cef8759bSmrg       else
277cef8759bSmrg 	{
278cef8759bSmrg 	  /* -mfpu=none is equivalent to -msoft-float.  */
279cef8759bSmrg 	  opts->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
280cef8759bSmrg 	  opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
281cef8759bSmrg 	  opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0;
282cef8759bSmrg 	}
283cef8759bSmrg       break;
284cef8759bSmrg 
285cef8759bSmrg     case OPT_mrecip:
286cef8759bSmrg       opts->x_rs6000_recip_name = (value) ? "default" : "none";
287cef8759bSmrg       break;
288cef8759bSmrg     }
289cef8759bSmrg   return true;
290cef8759bSmrg }
291cef8759bSmrg 
292cef8759bSmrg /* -fsplit-stack uses a field in the TCB, available with glibc-2.19.
293cef8759bSmrg    We also allow 2.18 because alignment padding guarantees that the
294cef8759bSmrg    space is available there too.  */
295cef8759bSmrg 
296cef8759bSmrg static bool
rs6000_supports_split_stack(bool report,struct gcc_options * opts ATTRIBUTE_UNUSED)297cef8759bSmrg rs6000_supports_split_stack (bool report,
298cef8759bSmrg 			     struct gcc_options *opts ATTRIBUTE_UNUSED)
299cef8759bSmrg {
300cef8759bSmrg #ifndef TARGET_GLIBC_MAJOR
301cef8759bSmrg #define TARGET_GLIBC_MAJOR 0
302cef8759bSmrg #endif
303cef8759bSmrg #ifndef TARGET_GLIBC_MINOR
304cef8759bSmrg #define TARGET_GLIBC_MINOR 0
305cef8759bSmrg #endif
306cef8759bSmrg   /* Note: Can't test DEFAULT_ABI here, it isn't set until later.  */
307cef8759bSmrg   if (TARGET_GLIBC_MAJOR * 1000 + TARGET_GLIBC_MINOR >= 2018
308cef8759bSmrg       && TARGET_64BIT
309cef8759bSmrg       && TARGET_ELF)
310cef8759bSmrg     return true;
311cef8759bSmrg 
312cef8759bSmrg   if (report)
313cef8759bSmrg     error ("%<-fsplit-stack%> currently only supported on PowerPC64 GNU/Linux with glibc-2.18 or later");
314cef8759bSmrg   return false;
315cef8759bSmrg }
316cef8759bSmrg 
317cef8759bSmrg #undef TARGET_HANDLE_OPTION
318cef8759bSmrg #define TARGET_HANDLE_OPTION rs6000_handle_option
319cef8759bSmrg 
320cef8759bSmrg #undef TARGET_OPTION_INIT_STRUCT
321cef8759bSmrg #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
322cef8759bSmrg 
323cef8759bSmrg #undef TARGET_OPTION_DEFAULT_PARAMS
324cef8759bSmrg #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
325cef8759bSmrg 
326cef8759bSmrg #undef TARGET_OPTION_OPTIMIZATION_TABLE
327cef8759bSmrg #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
328cef8759bSmrg 
329cef8759bSmrg #undef TARGET_SUPPORTS_SPLIT_STACK
330cef8759bSmrg #define TARGET_SUPPORTS_SPLIT_STACK rs6000_supports_split_stack
331cef8759bSmrg 
332cef8759bSmrg struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
333