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