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