]> gcc.gnu.org Git - gcc.git/blob - gcc/config/mep/mep-pragma.c
Update copyright years.
[gcc.git] / gcc / config / mep / mep-pragma.c
1 /* Definitions of Toshiba Media Processor
2 Copyright (C) 2001-2015 Free Software Foundation, Inc.
3 Contributed by Red Hat, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
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/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "diagnostic-core.h"
27 #include "c-family/c-pragma.h"
28 #include "cpplib.h"
29 #include "hard-reg-set.h"
30 #include "output.h" /* for decode_reg_name */
31 #include "mep-protos.h"
32 #include "hashtab.h"
33 #include "hash-set.h"
34 #include "vec.h"
35 #include "machmode.h"
36 #include "input.h"
37 #include "function.h"
38 #define MAX_RECOG_OPERANDS 10
39 #include "reload.h"
40 #include "target.h"
41
42 enum cw_which { CW_AVAILABLE, CW_CALL_SAVED };
43
44 /* This is normally provided by rtl.h but we can't include that file
45 here. It's safe to copy the definition here because we're only
46 using it internally; the value isn't passed to functions outside
47 this file. */
48 #ifndef INVALID_REGNUM
49 #define INVALID_REGNUM (~(unsigned int) 0)
50 #endif
51
52 static enum cpp_ttype
53 mep_pragma_lex (tree *valp)
54 {
55 enum cpp_ttype t = pragma_lex (valp);
56 if (t == CPP_EOF)
57 t = CPP_PRAGMA_EOL;
58 return t;
59 }
60
61 static void
62 mep_pragma_io_volatile (cpp_reader *reader ATTRIBUTE_UNUSED)
63 {
64 /* On off. */
65 tree val;
66 enum cpp_ttype type;
67 const char * str;
68
69 type = mep_pragma_lex (&val);
70 if (type == CPP_NAME)
71 {
72 str = IDENTIFIER_POINTER (val);
73
74 type = mep_pragma_lex (&val);
75 if (type != CPP_PRAGMA_EOL)
76 warning (0, "junk at end of #pragma io_volatile");
77
78 if (strcmp (str, "on") == 0)
79 {
80 target_flags |= MASK_IO_VOLATILE;
81 return;
82 }
83 if (strcmp (str, "off") == 0)
84 {
85 target_flags &= ~ MASK_IO_VOLATILE;
86 return;
87 }
88 }
89
90 error ("#pragma io_volatile takes only on or off");
91 }
92
93 static unsigned int
94 parse_cr_reg (const char * str)
95 {
96 unsigned int regno;
97
98 regno = decode_reg_name (str);
99 if (regno >= FIRST_PSEUDO_REGISTER)
100 return INVALID_REGNUM;
101
102 /* Verify that the regno is in CR_REGS. */
103 if (! TEST_HARD_REG_BIT (reg_class_contents[CR_REGS], regno))
104 return INVALID_REGNUM;
105 return regno;
106 }
107
108 static bool
109 parse_cr_set (HARD_REG_SET * set)
110 {
111 tree val;
112 enum cpp_ttype type;
113 unsigned int last_regno = INVALID_REGNUM;
114 bool do_range = false;
115
116 CLEAR_HARD_REG_SET (*set);
117
118 while ((type = mep_pragma_lex (&val)) != CPP_PRAGMA_EOL)
119 {
120 if (type == CPP_COMMA)
121 {
122 last_regno = INVALID_REGNUM;
123 do_range = false;
124 }
125 else if (type == CPP_ELLIPSIS)
126 {
127 if (last_regno == INVALID_REGNUM)
128 {
129 error ("invalid coprocessor register range");
130 return false;
131 }
132 do_range = true;
133 }
134 else if (type == CPP_NAME || type == CPP_STRING)
135 {
136 const char *str;
137 unsigned int regno, i;
138
139 if (TREE_CODE (val) == IDENTIFIER_NODE)
140 str = IDENTIFIER_POINTER (val);
141 else if (TREE_CODE (val) == STRING_CST)
142 str = TREE_STRING_POINTER (val);
143 else
144 gcc_unreachable ();
145
146 regno = parse_cr_reg (str);
147 if (regno == INVALID_REGNUM)
148 {
149 error ("invalid coprocessor register %qE", val);
150 return false;
151 }
152
153 if (do_range)
154 {
155 if (last_regno > regno)
156 i = regno, regno = last_regno;
157 else
158 i = last_regno;
159 do_range = false;
160 }
161 else
162 last_regno = i = regno;
163
164 while (i <= regno)
165 {
166 SET_HARD_REG_BIT (*set, i);
167 i++;
168 }
169 }
170 else
171 {
172 error ("malformed coprocessor register");
173 return false;
174 }
175 }
176 return true;
177 }
178
179 static void
180 mep_pragma_coprocessor_which (enum cw_which cw_which)
181 {
182 HARD_REG_SET set;
183
184 /* Process the balance of the pragma and turn it into a hard reg set. */
185 if (! parse_cr_set (&set))
186 return;
187
188 /* Process the collected hard reg set. */
189 switch (cw_which)
190 {
191 case CW_AVAILABLE:
192 {
193 int i;
194 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
195 if (TEST_HARD_REG_BIT (set, i))
196 fixed_regs[i] = 0;
197 }
198 break;
199
200 case CW_CALL_SAVED:
201 {
202 int i;
203 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
204 if (TEST_HARD_REG_BIT (set, i))
205 fixed_regs[i] = call_used_regs[i] = 0;
206 }
207 break;
208
209 default:
210 gcc_unreachable ();
211 }
212
213 /* Fix up register class hierarchy. */
214 mep_save_register_info ();
215 mep_reinit_regs ();
216
217 if (cfun == 0)
218 {
219 init_dummy_function_start ();
220 init_caller_save ();
221 expand_dummy_function_end ();
222 }
223 else
224 {
225 init_caller_save ();
226 }
227 }
228
229 static void
230 mep_pragma_coprocessor_width (void)
231 {
232 tree val;
233 enum cpp_ttype type;
234 HOST_WIDE_INT i;
235
236 type = mep_pragma_lex (&val);
237 switch (type)
238 {
239 case CPP_NUMBER:
240 if (! tree_fits_uhwi_p (val))
241 break;
242 i = tree_to_uhwi (val);
243 /* This pragma no longer has any effect. */
244 #if 0
245 if (i == 32)
246 target_flags &= ~MASK_64BIT_CR_REGS;
247 else if (i == 64)
248 target_flags |= MASK_64BIT_CR_REGS;
249 else
250 break;
251 targetm.init_builtins ();
252 #else
253 if (i != 32 && i != 64)
254 break;
255 #endif
256
257 type = mep_pragma_lex (&val);
258 if (type != CPP_PRAGMA_EOL)
259 warning (0, "junk at end of #pragma GCC coprocessor width");
260 return;
261
262 default:
263 break;
264 }
265
266 error ("#pragma GCC coprocessor width takes only 32 or 64");
267 }
268
269 static void
270 mep_pragma_coprocessor_subclass (void)
271 {
272 tree val;
273 enum cpp_ttype type;
274 HARD_REG_SET set;
275 int class_letter;
276 enum reg_class rclass;
277
278 type = mep_pragma_lex (&val);
279 if (type != CPP_CHAR)
280 goto syntax_error;
281 class_letter = tree_to_uhwi (val);
282 switch (class_letter)
283 {
284 case 'A':
285 rclass = USER0_REGS;
286 break;
287 case 'B':
288 rclass = USER1_REGS;
289 break;
290 case 'C':
291 rclass = USER2_REGS;
292 break;
293 case 'D':
294 rclass = USER3_REGS;
295 break;
296 default:
297 error ("#pragma GCC coprocessor subclass letter must be in [ABCD]");
298 return;
299 }
300 if (reg_class_size[rclass] > 0)
301 {
302 error ("#pragma GCC coprocessor subclass '%c' already defined",
303 class_letter);
304 return;
305 }
306
307 type = mep_pragma_lex (&val);
308 if (type != CPP_EQ)
309 goto syntax_error;
310
311 if (! parse_cr_set (&set))
312 return;
313
314 /* Fix up register class hierarchy. */
315 COPY_HARD_REG_SET (reg_class_contents[rclass], set);
316 mep_init_regs ();
317 return;
318
319 syntax_error:
320 error ("malformed #pragma GCC coprocessor subclass");
321 }
322
323 static void
324 mep_pragma_disinterrupt (cpp_reader *reader ATTRIBUTE_UNUSED)
325 {
326 tree val;
327 enum cpp_ttype type;
328 int saw_one = 0;
329
330 for (;;)
331 {
332 type = mep_pragma_lex (&val);
333 if (type == CPP_COMMA)
334 continue;
335 if (type != CPP_NAME)
336 break;
337 mep_note_pragma_disinterrupt (IDENTIFIER_POINTER (val));
338 saw_one = 1;
339 }
340 if (!saw_one || type != CPP_PRAGMA_EOL)
341 {
342 error ("malformed #pragma disinterrupt");
343 return;
344 }
345 }
346
347 static void
348 mep_pragma_coprocessor (cpp_reader *reader ATTRIBUTE_UNUSED)
349 {
350 tree val;
351 enum cpp_ttype type;
352
353 type = mep_pragma_lex (&val);
354 if (type != CPP_NAME)
355 {
356 error ("malformed #pragma GCC coprocessor");
357 return;
358 }
359
360 if (!TARGET_COP)
361 error ("coprocessor not enabled");
362
363 if (strcmp (IDENTIFIER_POINTER (val), "available") == 0)
364 mep_pragma_coprocessor_which (CW_AVAILABLE);
365 else if (strcmp (IDENTIFIER_POINTER (val), "call_saved") == 0)
366 mep_pragma_coprocessor_which (CW_CALL_SAVED);
367 else if (strcmp (IDENTIFIER_POINTER (val), "width") == 0)
368 mep_pragma_coprocessor_width ();
369 else if (strcmp (IDENTIFIER_POINTER (val), "subclass") == 0)
370 mep_pragma_coprocessor_subclass ();
371 else
372 error ("unknown #pragma GCC coprocessor %E", val);
373 }
374
375 static void
376 mep_pragma_call (cpp_reader *reader ATTRIBUTE_UNUSED)
377 {
378 tree val;
379 enum cpp_ttype type;
380 int saw_one = 0;
381
382 for (;;)
383 {
384 type = mep_pragma_lex (&val);
385 if (type == CPP_COMMA)
386 continue;
387 if (type != CPP_NAME)
388 break;
389 mep_note_pragma_call (IDENTIFIER_POINTER (val));
390 saw_one = 1;
391 }
392 if (!saw_one || type != CPP_PRAGMA_EOL)
393 {
394 error ("malformed #pragma call");
395 return;
396 }
397 }
398
399 void
400 mep_register_pragmas (void)
401 {
402 c_register_pragma ("custom", "io_volatile", mep_pragma_io_volatile);
403 c_register_pragma ("GCC", "coprocessor", mep_pragma_coprocessor);
404 c_register_pragma (0, "disinterrupt", mep_pragma_disinterrupt);
405 c_register_pragma (0, "call", mep_pragma_call);
406 }
This page took 0.055185 seconds and 5 git commands to generate.