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