]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/common/config/rs6000/rs6000-common.c
tree-diagnostic (struct loc_t): Rename into struct loc_map_pair.
[thirdparty/gcc.git] / gcc / common / config / rs6000 / rs6000-common.c
CommitLineData
677f3fa8
JM
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"
4c77620d 31#include "params.h"
677f3fa8
JM
32
33/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
34static 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
42static void
43rs6000_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
4c77620d
JM
55/* Implement TARGET_OPTION_DEFAULT_PARAMS. */
56
57static void
58rs6000_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
677f3fa8
JM
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
73static bool
74rs6000_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
206 error_at (loc, "unknown -mdebug-%s switch", q);
207
208 if (invert)
209 opts->x_rs6000_debug &= ~mask;
210 else
211 opts->x_rs6000_debug |= mask;
212 }
213 break;
214
215#ifdef TARGET_USES_SYSV4_OPT
216 case OPT_mrelocatable:
217 if (value == 1)
218 {
219 opts->x_target_flags |= MASK_MINIMAL_TOC;
220 opts_set->x_target_flags |= MASK_MINIMAL_TOC;
221 opts->x_TARGET_NO_FP_IN_TOC = 1;
222 }
223 break;
224
225 case OPT_mrelocatable_lib:
226 if (value == 1)
227 {
228 opts->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
229 opts_set->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
230 opts->x_TARGET_NO_FP_IN_TOC = 1;
231 }
232 else
233 {
234 opts->x_target_flags &= ~MASK_RELOCATABLE;
235 opts_set->x_target_flags |= MASK_RELOCATABLE;
236 }
237 break;
238#endif
239
240 case OPT_mabi_altivec:
241 /* Enabling the AltiVec ABI turns off the SPE ABI. */
242 opts->x_rs6000_spe_abi = 0;
243 break;
244
245 case OPT_mabi_spe:
246 opts->x_rs6000_altivec_abi = 0;
247 break;
248
249 case OPT_mlong_double_:
250 if (value != 64 && value != 128)
251 {
252 error_at (loc, "unknown switch -mlong-double-%s", arg);
253 opts->x_rs6000_long_double_type_size
254 = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
255 return false;
256 }
257 break;
258
259 case OPT_msingle_float:
260 if (!TARGET_SINGLE_FPU)
261 warning_at (loc, 0,
262 "-msingle-float option equivalent to -mhard-float");
263 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
264 opts->x_rs6000_double_float = 0;
265 opts->x_target_flags &= ~MASK_SOFT_FLOAT;
266 opts_set->x_target_flags |= MASK_SOFT_FLOAT;
267 break;
268
269 case OPT_mdouble_float:
270 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
271 opts->x_rs6000_single_float = 1;
272 opts->x_target_flags &= ~MASK_SOFT_FLOAT;
273 opts_set->x_target_flags |= MASK_SOFT_FLOAT;
274 break;
275
276 case OPT_msimple_fpu:
277 if (!TARGET_SINGLE_FPU)
278 warning_at (loc, 0, "-msimple-fpu option ignored");
279 break;
280
281 case OPT_mhard_float:
282 /* -mhard_float implies -msingle-float and -mdouble-float. */
283 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1;
284 break;
285
286 case OPT_msoft_float:
287 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
288 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0;
289 break;
290
291 case OPT_mfpu_:
292 fpu_type = (enum fpu_type_t) value;
293 if (fpu_type != FPU_NONE)
294 {
295 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on
296 HARD_FLOAT. */
297 opts->x_target_flags &= ~MASK_SOFT_FLOAT;
298 opts_set->x_target_flags |= MASK_SOFT_FLOAT;
299 opts->x_rs6000_xilinx_fpu = 1;
300 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
301 opts->x_rs6000_single_float = 1;
302 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
303 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1;
304 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
305 opts->x_rs6000_simple_fpu = 1;
306 }
307 else
308 {
309 /* -mfpu=none is equivalent to -msoft-float. */
310 opts->x_target_flags |= MASK_SOFT_FLOAT;
311 opts_set->x_target_flags |= MASK_SOFT_FLOAT;
312 opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0;
313 }
314 break;
315
316 case OPT_mrecip:
317 opts->x_rs6000_recip_name = (value) ? "default" : "none";
318 break;
319 }
320 return true;
321}
322
323#undef TARGET_HANDLE_OPTION
324#define TARGET_HANDLE_OPTION rs6000_handle_option
325
326#undef TARGET_OPTION_INIT_STRUCT
327#define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
328
4c77620d
JM
329#undef TARGET_OPTION_DEFAULT_PARAMS
330#define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
331
677f3fa8
JM
332#undef TARGET_OPTION_OPTIMIZATION_TABLE
333#define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
334
335#undef TARGET_DEFAULT_TARGET_FLAGS
336#define TARGET_DEFAULT_TARGET_FLAGS \
337 (TARGET_DEFAULT)
338
339struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;