OSDN Git Service

PR c/42312
[pf3gnuchains/gcc-fork.git] / gcc / config / mep / mep-pragma.c
1 /* Definitions of Toshiba Media Processor
2    Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007, 2009 Free
3    Software Foundation, Inc.  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 <stdio.h>
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "toplev.h"
29 #include "c-pragma.h"
30 #include "cpplib.h"
31 #include "hard-reg-set.h"
32 #include "output.h"
33 #include "mep-protos.h"
34 #include "function.h"
35 #define MAX_RECOG_OPERANDS 10
36 #include "reload.h"
37 #include "target.h"
38
39 enum cw_which { CW_AVAILABLE, CW_CALL_SAVED };
40
41 static enum cpp_ttype
42 mep_pragma_lex (tree *valp)
43 {
44   enum cpp_ttype t = pragma_lex (valp);
45   if (t == CPP_EOF)
46     t = CPP_PRAGMA_EOL;
47   return t;
48 }
49
50 static void
51 mep_pragma_io_volatile (cpp_reader *reader ATTRIBUTE_UNUSED)
52 {
53   /* On off.  */
54   tree val;
55   enum cpp_ttype type;
56   const char * str;
57
58   type = mep_pragma_lex (&val);
59   if (type == CPP_NAME)
60     {
61       str = IDENTIFIER_POINTER (val);
62
63       type = mep_pragma_lex (&val);
64       if (type != CPP_PRAGMA_EOL)
65         warning (0, "junk at end of #pragma io_volatile");
66
67       if (strcmp (str, "on") == 0)
68         {
69           target_flags |= MASK_IO_VOLATILE;
70           return;
71         }
72       if (strcmp (str, "off") == 0)
73         {
74           target_flags &= ~ MASK_IO_VOLATILE;
75           return;
76         }
77     }
78
79   error ("#pragma io_volatile takes only on or off");
80 }
81
82 static unsigned int
83 parse_cr_reg (const char * str)
84 {
85   unsigned int regno;
86
87   regno = decode_reg_name (str);
88   if (regno >= FIRST_PSEUDO_REGISTER)
89     return INVALID_REGNUM;
90
91   /* Verify that the regno is in CR_REGS.  */
92   if (! TEST_HARD_REG_BIT (reg_class_contents[CR_REGS], regno))
93     return INVALID_REGNUM;
94   return regno;
95 }
96
97 static bool
98 parse_cr_set (HARD_REG_SET * set)
99 {
100   tree val;
101   enum cpp_ttype type;
102   unsigned int last_regno = INVALID_REGNUM;
103   bool do_range = false;
104
105   CLEAR_HARD_REG_SET (*set);
106
107   while ((type = mep_pragma_lex (&val)) != CPP_PRAGMA_EOL)
108     {
109       if (type == CPP_COMMA)
110         {
111           last_regno = INVALID_REGNUM;
112           do_range = false;
113         }
114       else if (type == CPP_ELLIPSIS)
115         {
116           if (last_regno == INVALID_REGNUM)
117             {
118               error ("invalid coprocessor register range");
119               return false;
120             }
121           do_range = true;
122         }
123       else if (type == CPP_NAME || type == CPP_STRING)
124         {
125           const char *str;
126           unsigned int regno, i;
127
128           if (TREE_CODE (val) == IDENTIFIER_NODE)
129             str = IDENTIFIER_POINTER (val);
130           else if (TREE_CODE (val) == STRING_CST)
131             str = TREE_STRING_POINTER (val);
132           else
133             gcc_unreachable ();
134
135           regno = parse_cr_reg (str);
136           if (regno == INVALID_REGNUM)
137             {
138               error ("invalid coprocessor register %qE", val);
139               return false;
140             }
141
142           if (do_range)
143             {
144               if (last_regno > regno)
145                 i = regno, regno = last_regno;
146               else
147                 i = last_regno;
148               do_range = false;
149             }
150           else
151             last_regno = i = regno;
152
153           while (i <= regno)
154             {
155               SET_HARD_REG_BIT (*set, i);
156               i++;
157             }
158         }
159       else
160         {
161           error ("malformed coprocessor register");
162           return false;
163         }
164     }
165   return true;
166 }
167
168 static void
169 mep_pragma_coprocessor_which (enum cw_which cw_which)
170 {
171   HARD_REG_SET set;
172
173   /* Process the balance of the pragma and turn it into a hard reg set.  */
174   if (! parse_cr_set (&set))
175     return;
176
177   /* Process the collected hard reg set.  */
178   switch (cw_which)
179     {
180     case CW_AVAILABLE:
181       {
182         int i;
183         for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
184           if (TEST_HARD_REG_BIT (set, i))
185             fixed_regs[i] = 0;
186       }
187       break;
188
189     case CW_CALL_SAVED:
190       {
191         int i;
192         for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
193           if (TEST_HARD_REG_BIT (set, i))
194             fixed_regs[i] = call_used_regs[i] = 0;
195       }
196       break;
197
198     default:
199       gcc_unreachable ();
200     }
201
202   /* Fix up register class hierarchy.  */
203   save_register_info ();
204   reinit_regs ();
205
206   if (cfun == 0)
207     {
208       init_dummy_function_start ();
209       init_caller_save ();
210       expand_dummy_function_end ();
211     }
212   else
213     {
214       init_caller_save ();
215     }
216 }
217
218 static void
219 mep_pragma_coprocessor_width (void)
220 {
221   tree val;
222   enum cpp_ttype type;
223   HOST_WIDE_INT i;
224
225   type = mep_pragma_lex (&val);
226   switch (type)
227     {
228     case CPP_NUMBER:
229       if (! host_integerp (val, 1))
230         break;
231       i = tree_low_cst (val, 1);
232       /* This pragma no longer has any effect.  */
233 #if 0
234       if (i == 32)
235         target_flags &= ~MASK_64BIT_CR_REGS;
236       else if (i == 64)
237         target_flags |= MASK_64BIT_CR_REGS;
238       else
239         break;
240       targetm.init_builtins ();
241 #else
242       if (i != 32 && i != 64)
243         break;
244 #endif
245
246       type = mep_pragma_lex (&val);
247       if (type != CPP_PRAGMA_EOL)
248         warning (0, "junk at end of #pragma GCC coprocessor width");
249       return;
250
251     default:
252       break;
253     }
254
255   error ("#pragma GCC coprocessor width takes only 32 or 64");
256 }
257
258 static void
259 mep_pragma_coprocessor_subclass (void)
260 {
261   tree val;
262   enum cpp_ttype type;
263   HARD_REG_SET set;
264   int class_letter;
265   enum reg_class class;
266
267   type = mep_pragma_lex (&val);
268   if (type != CPP_CHAR)
269     goto syntax_error;
270   class_letter = tree_low_cst (val, 1);
271   if (class_letter >= 'A' && class_letter <= 'D')
272     class = class_letter - 'A' + USER0_REGS;
273   else
274     {
275       error ("#pragma GCC coprocessor subclass letter must be in [ABCD]");
276       return;
277     }
278   if (reg_class_size[class] > 0)
279     {
280       error ("#pragma GCC coprocessor subclass '%c' already defined",
281              class_letter);
282       return;
283     }
284
285   type = mep_pragma_lex (&val);
286   if (type != CPP_EQ)
287     goto syntax_error;
288
289   if (! parse_cr_set (&set))
290     return;
291
292   /* Fix up register class hierarchy.  */
293   COPY_HARD_REG_SET (reg_class_contents[class], set);
294   init_regs ();
295   return;
296
297  syntax_error:
298   error ("malformed #pragma GCC coprocessor subclass");
299 }
300
301 static void
302 mep_pragma_disinterrupt (cpp_reader *reader ATTRIBUTE_UNUSED)
303 {
304   tree val;
305   enum cpp_ttype type;
306   int saw_one = 0;
307
308   for (;;)
309     {
310       type = mep_pragma_lex (&val);
311       if (type == CPP_COMMA)
312         continue;
313       if (type != CPP_NAME)
314         break;
315       mep_note_pragma_disinterrupt (IDENTIFIER_POINTER (val));
316       saw_one = 1;
317     }
318   if (!saw_one || type != CPP_PRAGMA_EOL)
319     {
320       error ("malformed #pragma disinterrupt");
321       return;
322     }
323 }
324
325 static void
326 mep_pragma_coprocessor (cpp_reader *reader ATTRIBUTE_UNUSED)
327 {
328   tree val;
329   enum cpp_ttype type;
330
331   type = mep_pragma_lex (&val);
332   if (type != CPP_NAME)
333     {
334       error ("malformed #pragma GCC coprocessor");
335       return;
336     }
337
338   if (!TARGET_COP)
339     error ("coprocessor not enabled");
340
341   if (strcmp (IDENTIFIER_POINTER (val), "available") == 0)
342     mep_pragma_coprocessor_which (CW_AVAILABLE);
343   else if (strcmp (IDENTIFIER_POINTER (val), "call_saved") == 0)
344     mep_pragma_coprocessor_which (CW_CALL_SAVED);
345   else if (strcmp (IDENTIFIER_POINTER (val), "width") == 0)
346     mep_pragma_coprocessor_width ();
347   else if (strcmp (IDENTIFIER_POINTER (val), "subclass") == 0)
348     mep_pragma_coprocessor_subclass ();
349   else
350     error ("unknown #pragma GCC coprocessor %E", val);
351 }
352
353 static void
354 mep_pragma_call (cpp_reader *reader ATTRIBUTE_UNUSED)
355 {
356   tree val;
357   enum cpp_ttype type;
358   int saw_one = 0;
359
360   for (;;)
361     {
362       type = mep_pragma_lex (&val);
363       if (type == CPP_COMMA)
364         continue;
365       if (type != CPP_NAME)
366         break;
367       mep_note_pragma_call (IDENTIFIER_POINTER (val));
368       saw_one = 1;
369     }
370   if (!saw_one || type != CPP_PRAGMA_EOL)
371     {
372       error ("malformed #pragma call");
373       return;
374     }
375 }
376
377 void
378 mep_register_pragmas (void)
379 {
380   c_register_pragma ("custom", "io_volatile", mep_pragma_io_volatile);
381   c_register_pragma ("GCC", "coprocessor", mep_pragma_coprocessor);
382   c_register_pragma (0, "disinterrupt", mep_pragma_disinterrupt);
383   c_register_pragma (0, "call", mep_pragma_call);
384 }