xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/avr/avr-c.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /* Copyright (C) 2009-2013 Free Software Foundation, Inc.
2    Contributed by Anatoly Sokolov (aesok@post.ru)
3 
4    This file is part of GCC.
5 
6    GCC is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    GCC is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING3.  If not see
18    <http://www.gnu.org/licenses/>.  */
19 
20 /* Not included in avr.c since this requires C front end.  */
21 
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tm_p.h"
27 #include "cpplib.h"
28 #include "tree.h"
29 #include "target.h"
30 #include "c-family/c-common.h"
31 #include "langhooks.h"
32 
33 
34 /* IDs for all the AVR builtins.  */
35 
36 enum avr_builtin_id
37   {
38 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)  \
39     AVR_BUILTIN_ ## NAME,
40 #include "builtins.def"
41 #undef DEF_BUILTIN
42 
43     AVR_BUILTIN_COUNT
44   };
45 
46 
47 /* Implement `TARGET_RESOLVE_OVERLOADED_PLUGIN'.  */
48 
49 static tree
50 avr_resolve_overloaded_builtin (unsigned int iloc, tree fndecl, void *vargs)
51 {
52   tree type0, type1, fold = NULL_TREE;
53   enum avr_builtin_id id = AVR_BUILTIN_COUNT;
54   location_t loc = (location_t) iloc;
55   vec<tree, va_gc> &args = * (vec<tree, va_gc>*) vargs;
56 
57   switch (DECL_FUNCTION_CODE (fndecl))
58     {
59     default:
60       break;
61 
62     case AVR_BUILTIN_ABSFX:
63       if (args.length() != 1)
64         {
65           error_at (loc, "%qs expects 1 argument but %d given",
66                     "absfx", (int) args.length());
67 
68           fold = error_mark_node;
69           break;
70         }
71 
72       type0 = TREE_TYPE (args[0]);
73 
74       if (!FIXED_POINT_TYPE_P (type0))
75         {
76           error_at (loc, "%qs expects a fixed-point value as argument",
77                     "absfx");
78 
79           fold = error_mark_node;
80         }
81 
82       switch (TYPE_MODE (type0))
83         {
84         case QQmode: id = AVR_BUILTIN_ABSHR; break;
85         case HQmode: id = AVR_BUILTIN_ABSR; break;
86         case SQmode: id = AVR_BUILTIN_ABSLR; break;
87         case DQmode: id = AVR_BUILTIN_ABSLLR; break;
88 
89         case HAmode: id = AVR_BUILTIN_ABSHK; break;
90         case SAmode: id = AVR_BUILTIN_ABSK; break;
91         case DAmode: id = AVR_BUILTIN_ABSLK; break;
92         case TAmode: id = AVR_BUILTIN_ABSLLK; break;
93 
94         case UQQmode:
95         case UHQmode:
96         case USQmode:
97         case UDQmode:
98         case UHAmode:
99         case USAmode:
100         case UDAmode:
101         case UTAmode:
102           warning_at (loc, 0, "using %qs with unsigned type has no effect",
103                       "absfx");
104           return args[0];
105 
106         default:
107           error_at (loc, "no matching fixed-point overload found for %qs",
108                     "absfx");
109 
110           fold = error_mark_node;
111           break;
112         }
113 
114       fold = targetm.builtin_decl (id, true);
115 
116       if (fold != error_mark_node)
117         fold = build_function_call_vec (loc, fold, &args, NULL);
118 
119       break; // absfx
120 
121     case AVR_BUILTIN_ROUNDFX:
122       if (args.length() != 2)
123         {
124           error_at (loc, "%qs expects 2 arguments but %d given",
125                     "roundfx", (int) args.length());
126 
127           fold = error_mark_node;
128           break;
129         }
130 
131       type0 = TREE_TYPE (args[0]);
132       type1 = TREE_TYPE (args[1]);
133 
134       if (!FIXED_POINT_TYPE_P (type0))
135         {
136           error_at (loc, "%qs expects a fixed-point value as first argument",
137                     "roundfx");
138 
139           fold = error_mark_node;
140         }
141 
142       if (!INTEGRAL_TYPE_P (type1))
143         {
144           error_at (loc, "%qs expects an integer value as second argument",
145                     "roundfx");
146 
147           fold = error_mark_node;
148         }
149 
150       switch (TYPE_MODE (type0))
151         {
152         case QQmode: id = AVR_BUILTIN_ROUNDHR; break;
153         case HQmode: id = AVR_BUILTIN_ROUNDR; break;
154         case SQmode: id = AVR_BUILTIN_ROUNDLR; break;
155         case DQmode: id = AVR_BUILTIN_ROUNDLLR; break;
156 
157         case UQQmode: id = AVR_BUILTIN_ROUNDUHR; break;
158         case UHQmode: id = AVR_BUILTIN_ROUNDUR; break;
159         case USQmode: id = AVR_BUILTIN_ROUNDULR; break;
160         case UDQmode: id = AVR_BUILTIN_ROUNDULLR; break;
161 
162         case HAmode: id = AVR_BUILTIN_ROUNDHK; break;
163         case SAmode: id = AVR_BUILTIN_ROUNDK; break;
164         case DAmode: id = AVR_BUILTIN_ROUNDLK; break;
165         case TAmode: id = AVR_BUILTIN_ROUNDLLK; break;
166 
167         case UHAmode: id = AVR_BUILTIN_ROUNDUHK; break;
168         case USAmode: id = AVR_BUILTIN_ROUNDUK; break;
169         case UDAmode: id = AVR_BUILTIN_ROUNDULK; break;
170         case UTAmode: id = AVR_BUILTIN_ROUNDULLK; break;
171 
172         default:
173           error_at (loc, "no matching fixed-point overload found for %qs",
174                     "roundfx");
175 
176           fold = error_mark_node;
177           break;
178         }
179 
180       fold = targetm.builtin_decl (id, true);
181 
182       if (fold != error_mark_node)
183         fold = build_function_call_vec (loc, fold, &args, NULL);
184 
185       break; // roundfx
186 
187     case AVR_BUILTIN_COUNTLSFX:
188       if (args.length() != 1)
189         {
190           error_at (loc, "%qs expects 1 argument but %d given",
191                     "countlsfx", (int) args.length());
192 
193           fold = error_mark_node;
194           break;
195         }
196 
197       type0 = TREE_TYPE (args[0]);
198 
199       if (!FIXED_POINT_TYPE_P (type0))
200         {
201           error_at (loc, "%qs expects a fixed-point value as first argument",
202                     "countlsfx");
203 
204           fold = error_mark_node;
205         }
206 
207       switch (TYPE_MODE (type0))
208         {
209         case QQmode: id = AVR_BUILTIN_COUNTLSHR; break;
210         case HQmode: id = AVR_BUILTIN_COUNTLSR; break;
211         case SQmode: id = AVR_BUILTIN_COUNTLSLR; break;
212         case DQmode: id = AVR_BUILTIN_COUNTLSLLR; break;
213 
214         case UQQmode: id = AVR_BUILTIN_COUNTLSUHR; break;
215         case UHQmode: id = AVR_BUILTIN_COUNTLSUR; break;
216         case USQmode: id = AVR_BUILTIN_COUNTLSULR; break;
217         case UDQmode: id = AVR_BUILTIN_COUNTLSULLR; break;
218 
219         case HAmode: id = AVR_BUILTIN_COUNTLSHK; break;
220         case SAmode: id = AVR_BUILTIN_COUNTLSK; break;
221         case DAmode: id = AVR_BUILTIN_COUNTLSLK; break;
222         case TAmode: id = AVR_BUILTIN_COUNTLSLLK; break;
223 
224         case UHAmode: id = AVR_BUILTIN_COUNTLSUHK; break;
225         case USAmode: id = AVR_BUILTIN_COUNTLSUK; break;
226         case UDAmode: id = AVR_BUILTIN_COUNTLSULK; break;
227         case UTAmode: id = AVR_BUILTIN_COUNTLSULLK; break;
228 
229         default:
230           error_at (loc, "no matching fixed-point overload found for %qs",
231                     "countlsfx");
232 
233           fold = error_mark_node;
234           break;
235         }
236 
237       fold = targetm.builtin_decl (id, true);
238 
239       if (fold != error_mark_node)
240         fold = build_function_call_vec (loc, fold, &args, NULL);
241 
242       break; // countlsfx
243     }
244 
245   return fold;
246 }
247 
248 
249 /* Implement `REGISTER_TARGET_PRAGMAS'.  */
250 
251 void
252 avr_register_target_pragmas (void)
253 {
254   int i;
255 
256   gcc_assert (ADDR_SPACE_GENERIC == ADDR_SPACE_RAM);
257 
258   /* Register address spaces.  The order must be the same as in the respective
259      enum from avr.h (or designated initializers must be used in avr.c).  */
260 
261   for (i = 0; i < ADDR_SPACE_COUNT; i++)
262     {
263       gcc_assert (i == avr_addrspace[i].id);
264 
265       if (!ADDR_SPACE_GENERIC_P (i))
266         c_register_addr_space (avr_addrspace[i].name, avr_addrspace[i].id);
267     }
268 
269   targetm.resolve_overloaded_builtin = avr_resolve_overloaded_builtin;
270 }
271 
272 
273 /* Transform LO into uppercase and write the result to UP.
274    You must provide enough space for UP.  Return UP.  */
275 
276 static char*
277 avr_toupper (char *up, const char *lo)
278 {
279   char *up0 = up;
280 
281   for (; *lo; lo++, up++)
282     *up = TOUPPER (*lo);
283 
284   *up = '\0';
285 
286   return up0;
287 }
288 
289 /* Worker function for TARGET_CPU_CPP_BUILTINS.  */
290 
291 void
292 avr_cpu_cpp_builtins (struct cpp_reader *pfile)
293 {
294   int i;
295 
296   builtin_define_std ("AVR");
297 
298   if (avr_current_arch->macro)
299     cpp_define_formatted (pfile, "__AVR_ARCH__=%s", avr_current_arch->macro);
300   if (avr_current_device->macro)
301     cpp_define (pfile, avr_current_device->macro);
302   if (AVR_HAVE_RAMPD)    cpp_define (pfile, "__AVR_HAVE_RAMPD__");
303   if (AVR_HAVE_RAMPX)    cpp_define (pfile, "__AVR_HAVE_RAMPX__");
304   if (AVR_HAVE_RAMPY)    cpp_define (pfile, "__AVR_HAVE_RAMPY__");
305   if (AVR_HAVE_RAMPZ)    cpp_define (pfile, "__AVR_HAVE_RAMPZ__");
306   if (AVR_HAVE_ELPM)     cpp_define (pfile, "__AVR_HAVE_ELPM__");
307   if (AVR_HAVE_ELPMX)    cpp_define (pfile, "__AVR_HAVE_ELPMX__");
308   if (AVR_HAVE_MOVW)     cpp_define (pfile, "__AVR_HAVE_MOVW__");
309   if (AVR_HAVE_LPMX)     cpp_define (pfile, "__AVR_HAVE_LPMX__");
310 
311   if (avr_current_arch->asm_only)
312     cpp_define (pfile, "__AVR_ASM_ONLY__");
313   if (AVR_HAVE_MUL)
314     {
315       cpp_define (pfile, "__AVR_ENHANCED__");
316       cpp_define (pfile, "__AVR_HAVE_MUL__");
317     }
318   if (avr_current_arch->have_jmp_call)
319     {
320       cpp_define (pfile, "__AVR_MEGA__");
321       cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
322     }
323   if (AVR_XMEGA)
324     cpp_define (pfile, "__AVR_XMEGA__");
325   if (avr_current_arch->have_eijmp_eicall)
326     {
327       cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
328       cpp_define (pfile, "__AVR_3_BYTE_PC__");
329     }
330   else
331     {
332       cpp_define (pfile, "__AVR_2_BYTE_PC__");
333     }
334 
335   if (AVR_HAVE_8BIT_SP)
336     cpp_define (pfile, "__AVR_HAVE_8BIT_SP__");
337   else
338     cpp_define (pfile, "__AVR_HAVE_16BIT_SP__");
339 
340   if (avr_sp8)
341     cpp_define (pfile, "__AVR_SP8__");
342 
343   if (AVR_HAVE_SPH)
344     cpp_define (pfile, "__AVR_HAVE_SPH__");
345 
346   if (TARGET_NO_INTERRUPTS)
347     cpp_define (pfile, "__NO_INTERRUPTS__");
348 
349   if (avr_current_device->errata_skip)
350     {
351       cpp_define (pfile, "__AVR_ERRATA_SKIP__");
352 
353       if (avr_current_arch->have_jmp_call)
354         cpp_define (pfile, "__AVR_ERRATA_SKIP_JMP_CALL__");
355     }
356 
357   cpp_define_formatted (pfile, "__AVR_SFR_OFFSET__=0x%x",
358                         avr_current_arch->sfr_offset);
359 
360 #ifdef WITH_AVRLIBC
361   cpp_define (pfile, "__WITH_AVRLIBC__");
362 #endif /* WITH_AVRLIBC */
363 
364   /* Define builtin macros so that the user can easily query whether
365      non-generic address spaces (and which) are supported or not.
366      This is only supported for C.  For C++, a language extension is needed
367      (as mentioned in ISO/IEC DTR 18037; Annex F.2) which is not
368      implemented in GCC up to now.  */
369 
370   if (!strcmp (lang_hooks.name, "GNU C"))
371     {
372       for (i = 0; i < ADDR_SPACE_COUNT; i++)
373         if (!ADDR_SPACE_GENERIC_P (i)
374             /* Only supply __FLASH<n> macro if the address space is reasonable
375                for this target.  The address space qualifier itself is still
376                supported, but using it will throw an error.  */
377             && avr_addrspace[i].segment < avr_current_device->n_flash)
378           {
379             const char *name = avr_addrspace[i].name;
380             char *Name = (char*) alloca (1 + strlen (name));
381 
382             cpp_define (pfile, avr_toupper (Name, name));
383           }
384     }
385 
386   /* Define builtin macros so that the user can easily query whether or
387      not a specific builtin is available. */
388 
389 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)  \
390   cpp_define (pfile, "__BUILTIN_AVR_" #NAME);
391 #include "builtins.def"
392 #undef DEF_BUILTIN
393 
394   /* Builtin macros for the __int24 and __uint24 type.  */
395 
396   cpp_define_formatted (pfile, "__INT24_MAX__=8388607%s",
397                         INT_TYPE_SIZE == 8 ? "LL" : "L");
398   cpp_define (pfile, "__INT24_MIN__=(-__INT24_MAX__-1)");
399   cpp_define_formatted (pfile, "__UINT24_MAX__=16777215%s",
400                         INT_TYPE_SIZE == 8 ? "ULL" : "UL");
401 }
402