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