xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/v850/v850-c.c (revision 796c32c94f6e154afc9de0f63da35c91bb739b45)
1 /* v850 specific, C compiler specific functions.
2    Copyright (C) 2000-2015 Free Software Foundation, Inc.
3    Contributed by Jeff Law (law@cygnus.com).
4 
5 This file is part of GCC.
6 
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.
11 
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.
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 "cpplib.h"
26 #include "hash-set.h"
27 #include "machmode.h"
28 #include "vec.h"
29 #include "double-int.h"
30 #include "input.h"
31 #include "alias.h"
32 #include "symtab.h"
33 #include "wide-int.h"
34 #include "inchash.h"
35 #include "tree.h"
36 #include "stringpool.h"
37 #include "attribs.h"
38 #include "c-family/c-pragma.h"
39 #include "diagnostic-core.h"
40 #include "ggc.h"
41 #include "tm_p.h"
42 
43 #ifndef streq
44 #define streq(a,b) (strcmp (a, b) == 0)
45 #endif
46 
47 static int  pop_data_area          (v850_data_area);
48 static int  push_data_area         (v850_data_area);
49 static void mark_current_function_as_interrupt (void);
50 
51 /* Push a data area onto the stack.  */
52 
53 static int
54 push_data_area (v850_data_area data_area)
55 {
56   data_area_stack_element * elem;
57 
58   elem = (data_area_stack_element *) xmalloc (sizeof (* elem));
59 
60   if (elem == NULL)
61     return 0;
62 
63   elem->prev      = data_area_stack;
64   elem->data_area = data_area;
65 
66   data_area_stack = elem;
67 
68   return 1;
69 }
70 
71 /* Remove a data area from the stack.  */
72 
73 static int
74 pop_data_area (v850_data_area data_area)
75 {
76   if (data_area_stack == NULL)
77     warning (OPT_Wpragmas, "#pragma GHS endXXXX found without "
78 	     "previous startXXX");
79   else if (data_area != data_area_stack->data_area)
80     warning (OPT_Wpragmas, "#pragma GHS endXXX does not match "
81 	     "previous startXXX");
82   else
83     {
84       data_area_stack_element * elem;
85 
86       elem = data_area_stack;
87       data_area_stack = data_area_stack->prev;
88 
89       free (elem);
90 
91       return 1;
92     }
93 
94   return 0;
95 }
96 
97 /* Set the machine specific 'interrupt' attribute on the current function.  */
98 
99 static void
100 mark_current_function_as_interrupt (void)
101 {
102   tree name;
103 
104   if (current_function_decl ==  NULL_TREE)
105     {
106       warning (0, "cannot set interrupt attribute: no current function");
107       return;
108     }
109 
110   name = get_identifier ("interrupt");
111 
112   if (name == NULL_TREE || TREE_CODE (name) != IDENTIFIER_NODE)
113     {
114       warning (0, "cannot set interrupt attribute: no such identifier");
115       return;
116     }
117 
118   decl_attributes (&current_function_decl,
119 		   tree_cons (name, NULL_TREE, NULL_TREE), 0);
120 }
121 
122 
123 /* Support for GHS pragmata.  */
124 
125 void
126 ghs_pragma_section (cpp_reader * pfile ATTRIBUTE_UNUSED)
127 {
128   int repeat = 0;
129 
130   /* #pragma ghs section [name = alias [, name = alias [, ...]]] */
131   do
132     {
133       tree x;
134       enum cpp_ttype type;
135       tree sect_ident;
136       const char *sect, *alias;
137       enum GHS_section_kind kind;
138 
139       type = pragma_lex (&x);
140 
141       if (type == CPP_EOF && !repeat)
142 	goto reset;
143       else if (type == CPP_NAME)
144 	{
145 	  sect_ident = x;
146 	  sect = IDENTIFIER_POINTER (sect_ident);
147 	}
148       else
149 	goto bad;
150       repeat = 0;
151 
152       if (pragma_lex (&x) != CPP_EQ)
153 	goto bad;
154       if (pragma_lex (&x) != CPP_NAME)
155 	goto bad;
156 
157       alias = IDENTIFIER_POINTER (x);
158 
159       type = pragma_lex (&x);
160       if (type == CPP_COMMA)
161 	repeat = 1;
162       else if (type != CPP_EOF)
163 	warning (OPT_Wpragmas, "junk at end of #pragma ghs section");
164 
165       if      (streq (sect, "data"))    kind = GHS_SECTION_KIND_DATA;
166       else if (streq (sect, "text"))    kind = GHS_SECTION_KIND_TEXT;
167       else if (streq (sect, "rodata"))  kind = GHS_SECTION_KIND_RODATA;
168       else if (streq (sect, "const"))   kind = GHS_SECTION_KIND_RODATA;
169       else if (streq (sect, "rosdata")) kind = GHS_SECTION_KIND_ROSDATA;
170       else if (streq (sect, "rozdata")) kind = GHS_SECTION_KIND_ROZDATA;
171       else if (streq (sect, "sdata"))   kind = GHS_SECTION_KIND_SDATA;
172       else if (streq (sect, "tdata"))   kind = GHS_SECTION_KIND_TDATA;
173       else if (streq (sect, "zdata"))   kind = GHS_SECTION_KIND_ZDATA;
174       /* According to GHS beta documentation, the following should not be
175 	 allowed!  */
176       else if (streq (sect, "bss"))     kind = GHS_SECTION_KIND_BSS;
177       else if (streq (sect, "zbss"))    kind = GHS_SECTION_KIND_ZDATA;
178       else
179 	{
180 	  warning (0, "unrecognized section name %qE", sect_ident);
181 	  return;
182 	}
183 
184       if (streq (alias, "default"))
185 	GHS_current_section_names [kind] = NULL;
186       else
187 	GHS_current_section_names [kind] = alias;
188     }
189   while (repeat);
190 
191   return;
192 
193  bad:
194   warning (OPT_Wpragmas, "malformed #pragma ghs section");
195   return;
196 
197  reset:
198   /* #pragma ghs section \n: Reset all section names back to their defaults.  */
199   {
200     int i;
201 
202     for (i = COUNT_OF_GHS_SECTION_KINDS; i--;)
203       GHS_current_section_names [i] = NULL;
204   }
205 }
206 
207 void
208 ghs_pragma_interrupt (cpp_reader * pfile ATTRIBUTE_UNUSED)
209 {
210   tree x;
211 
212   if (pragma_lex (&x) != CPP_EOF)
213     warning (OPT_Wpragmas, "junk at end of #pragma ghs interrupt");
214 
215   mark_current_function_as_interrupt ();
216 }
217 
218 void
219 ghs_pragma_starttda (cpp_reader * pfile ATTRIBUTE_UNUSED)
220 {
221   tree x;
222 
223   if (pragma_lex (&x) != CPP_EOF)
224     warning (OPT_Wpragmas, "junk at end of #pragma ghs starttda");
225 
226   push_data_area (DATA_AREA_TDA);
227 }
228 
229 void
230 ghs_pragma_startsda (cpp_reader * pfile ATTRIBUTE_UNUSED)
231 {
232   tree x;
233 
234   if (pragma_lex (&x) != CPP_EOF)
235     warning (OPT_Wpragmas, "junk at end of #pragma ghs startsda");
236 
237   push_data_area (DATA_AREA_SDA);
238 }
239 
240 void
241 ghs_pragma_startzda (cpp_reader * pfile ATTRIBUTE_UNUSED)
242 {
243   tree x;
244 
245   if (pragma_lex (&x) != CPP_EOF)
246     warning (OPT_Wpragmas, "junk at end of #pragma ghs startzda");
247 
248   push_data_area (DATA_AREA_ZDA);
249 }
250 
251 void
252 ghs_pragma_endtda (cpp_reader * pfile ATTRIBUTE_UNUSED)
253 {
254   tree x;
255 
256   if (pragma_lex (&x) != CPP_EOF)
257     warning (OPT_Wpragmas, "junk at end of #pragma ghs endtda");
258 
259   pop_data_area (DATA_AREA_TDA);
260 }
261 
262 void
263 ghs_pragma_endsda (cpp_reader * pfile ATTRIBUTE_UNUSED)
264 {
265   tree x;
266 
267   if (pragma_lex (&x) != CPP_EOF)
268     warning (OPT_Wpragmas, "junk at end of #pragma ghs endsda");
269 
270   pop_data_area (DATA_AREA_SDA);
271 }
272 
273 void
274 ghs_pragma_endzda (cpp_reader * pfile ATTRIBUTE_UNUSED)
275 {
276   tree x;
277 
278   if (pragma_lex (&x) != CPP_EOF)
279     warning (OPT_Wpragmas, "junk at end of #pragma ghs endzda");
280 
281   pop_data_area (DATA_AREA_ZDA);
282 }
283