[AArch64] Remember to cost operand 0 in FP compare-with-0.0 case
[official-gcc.git] / gcc / config / sol2-c.c
bloba73384c0f34f60dc118b2e4f916267bf38229f20
1 /* Solaris support needed only by C/C++ frontends.
2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
3 Contributed by CodeSourcery, LLC.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "options.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "stringpool.h"
36 #include "attribs.h"
37 #include "tm.h"
38 #include "tm_p.h"
40 #include "c-family/c-format.h"
41 #include "intl.h"
43 #include "cpplib.h"
44 #include "c-family/c-pragma.h"
45 #include "c-family/c-common.h"
47 /* cmn_err only accepts "l" and "ll". */
48 static const format_length_info cmn_err_length_specs[] =
50 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
51 { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
54 static const format_flag_spec cmn_err_flag_specs[] =
56 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
57 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
58 { 0, 0, 0, NULL, NULL, STD_C89 }
62 static const format_flag_pair cmn_err_flag_pairs[] =
64 { 0, 0, 0, 0 }
67 static const format_char_info bitfield_string_type =
68 { "b", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL };
70 static const format_char_info cmn_err_char_table[] =
72 /* C89 conversion specifiers. */
73 { "dD", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
74 { "oOxX",0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
75 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
76 { "c", 0, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
77 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "c", NULL },
78 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "cR", NULL },
79 { "b", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", &bitfield_string_type },
80 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
83 EXPORTED_CONST format_kind_info solaris_format_types[] = {
84 { "cmn_err", cmn_err_length_specs, cmn_err_char_table, "", NULL,
85 cmn_err_flag_specs, cmn_err_flag_pairs,
86 FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
87 'w', 0, 0, 0, 'L', 0,
88 &integer_type_node, &integer_type_node
92 /* Handle #pragma align ALIGNMENT (VAR [, VAR]...) */
94 static void
95 solaris_pragma_align (cpp_reader *pfile ATTRIBUTE_UNUSED)
97 tree t, x;
98 enum cpp_ttype ttype;
99 unsigned HOST_WIDE_INT low;
101 if (pragma_lex (&x) != CPP_NUMBER
102 || pragma_lex (&t) != CPP_OPEN_PAREN)
104 warning (0, "malformed %<#pragma align%>, ignoring");
105 return;
108 low = TREE_INT_CST_LOW (x);
109 if (!tree_fits_uhwi_p (x)
110 || (low != 1 && low != 2 && low != 4 && low != 8 && low != 16
111 && low != 32 && low != 64 && low != 128))
113 warning (0, "invalid alignment for %<#pragma align%>, ignoring");
114 return;
117 ttype = pragma_lex (&t);
118 if (ttype != CPP_NAME)
120 warning (0, "malformed %<#pragma align%>, ignoring");
121 return;
124 while (1)
126 tree decl = identifier_global_value (t);
127 if (decl && DECL_P (decl))
128 warning (0, "%<#pragma align%> must appear before the declaration of "
129 "%D, ignoring", decl);
130 else
131 solaris_pending_aligns = tree_cons (t, build_tree_list (NULL, x),
132 solaris_pending_aligns);
134 ttype = pragma_lex (&t);
135 if (ttype == CPP_COMMA)
137 ttype = pragma_lex (&t);
138 if (ttype != CPP_NAME)
140 warning (0, "malformed %<#pragma align%>");
141 return;
144 else if (ttype == CPP_CLOSE_PAREN)
146 if (pragma_lex (&t) != CPP_EOF)
147 warning (0, "junk at end of %<#pragma align%>");
148 return;
150 else
152 warning (0, "malformed %<#pragma align%>");
153 return;
158 /* Handle #pragma init (function [, function]...) */
160 static void
161 solaris_pragma_init (cpp_reader *pfile ATTRIBUTE_UNUSED)
163 tree t;
164 enum cpp_ttype ttype;
166 if (pragma_lex (&t) != CPP_OPEN_PAREN)
168 warning (0, "malformed %<#pragma init%>, ignoring");
169 return;
172 ttype = pragma_lex (&t);
173 if (ttype != CPP_NAME)
175 warning (0, "malformed %<#pragma init%>, ignoring");
176 return;
179 while (1)
181 tree decl = identifier_global_value (t);
182 if (decl && DECL_P (decl))
184 tree attrs = build_tree_list (get_identifier ("init"),
185 NULL);
186 TREE_USED (decl) = 1;
187 DECL_PRESERVE_P (decl) = 1;
188 decl_attributes (&decl, attrs, 0);
190 else
191 solaris_pending_inits = tree_cons (t, NULL, solaris_pending_inits);
193 ttype = pragma_lex (&t);
194 if (ttype == CPP_COMMA)
196 ttype = pragma_lex (&t);
197 if (ttype != CPP_NAME)
199 warning (0, "malformed %<#pragma init%>");
200 return;
203 else if (ttype == CPP_CLOSE_PAREN)
205 if (pragma_lex (&t) != CPP_EOF)
206 warning (0, "junk at end of %<#pragma init%>");
207 return;
209 else
211 warning (0, "malformed %<#pragma init%>");
212 return;
217 /* Handle #pragma fini (function [, function]...) */
219 static void
220 solaris_pragma_fini (cpp_reader *pfile ATTRIBUTE_UNUSED)
222 tree t;
223 enum cpp_ttype ttype;
225 if (pragma_lex (&t) != CPP_OPEN_PAREN)
227 warning (0, "malformed %<#pragma fini%>, ignoring");
228 return;
231 ttype = pragma_lex (&t);
232 if (ttype != CPP_NAME)
234 warning (0, "malformed %<#pragma fini%>, ignoring");
235 return;
238 while (1)
240 tree decl = identifier_global_value (t);
241 if (decl && DECL_P (decl))
243 tree attrs = build_tree_list (get_identifier ("fini"),
244 NULL);
245 TREE_USED (decl) = 1;
246 DECL_PRESERVE_P (decl) = 1;
247 decl_attributes (&decl, attrs, 0);
249 else
250 solaris_pending_finis = tree_cons (t, NULL, solaris_pending_finis);
252 ttype = pragma_lex (&t);
253 if (ttype == CPP_COMMA)
255 ttype = pragma_lex (&t);
256 if (ttype != CPP_NAME)
258 warning (0, "malformed %<#pragma fini%>");
259 return;
262 else if (ttype == CPP_CLOSE_PAREN)
264 if (pragma_lex (&t) != CPP_EOF)
265 warning (0, "junk at end of %<#pragma fini%>");
266 return;
268 else
270 warning (0, "malformed %<#pragma fini%>");
271 return;
276 /* Register Solaris-specific #pragma directives. */
278 void
279 solaris_register_pragmas (void)
281 c_register_pragma_with_expansion (0, "align", solaris_pragma_align);
282 c_register_pragma (0, "init", solaris_pragma_init);
283 c_register_pragma (0, "fini", solaris_pragma_fini);