OSDN Git Service

Enable target specific builtins and macros when using the target attribute or pragma...
[pf3gnuchains/gcc-fork.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;