xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/avr/avr-c.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Copyright (C) 2009-2015 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 "hash-set.h"
29 #include "machmode.h"
30 #include "vec.h"
31 #include "double-int.h"
32 #include "input.h"
33 #include "alias.h"
34 #include "symtab.h"
35 #include "wide-int.h"
36 #include "inchash.h"
37 #include "tree.h"
38 #include "stor-layout.h"
39 #include "target.h"
40 #include "c-family/c-common.h"
41 #include "langhooks.h"
42 
43 
44 /* IDs for all the AVR builtins.  */
45 
46 enum avr_builtin_id
47   {
48 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)  \
49     AVR_BUILTIN_ ## NAME,
50 #include "builtins.def"
51 #undef DEF_BUILTIN
52 
53     AVR_BUILTIN_COUNT
54   };
55 
56 
57 /* Implement `TARGET_RESOLVE_OVERLOADED_PLUGIN'.  */
58 
59 static tree
60 avr_resolve_overloaded_builtin (unsigned int iloc, tree fndecl, void *vargs)
61 {
62   tree type0, type1, fold = NULL_TREE;
63   enum avr_builtin_id id = AVR_BUILTIN_COUNT;
64   location_t loc = (location_t) iloc;
65   vec<tree, va_gc> &args = * (vec<tree, va_gc>*) vargs;
66 
67   switch (DECL_FUNCTION_CODE (fndecl))
68     {
69     default:
70       break;
71 
72     case AVR_BUILTIN_ABSFX:
73       if (args.length() != 1)
74         {
75           error_at (loc, "%qs expects 1 argument but %d given",
76                     "absfx", (int) args.length());
77 
78           fold = error_mark_node;
79           break;
80         }
81 
82       type0 = TREE_TYPE (args[0]);
83 
84       if (!FIXED_POINT_TYPE_P (type0))
85         {
86           error_at (loc, "%qs expects a fixed-point value as argument",
87                     "absfx");
88 
89           fold = error_mark_node;
90         }
91 
92       switch (TYPE_MODE (type0))
93         {
94         case QQmode: id = AVR_BUILTIN_ABSHR; break;
95         case HQmode: id = AVR_BUILTIN_ABSR; break;
96         case SQmode: id = AVR_BUILTIN_ABSLR; break;
97         case DQmode: id = AVR_BUILTIN_ABSLLR; break;
98 
99         case HAmode: id = AVR_BUILTIN_ABSHK; break;
100         case SAmode: id = AVR_BUILTIN_ABSK; break;
101         case DAmode: id = AVR_BUILTIN_ABSLK; break;
102         case TAmode: id = AVR_BUILTIN_ABSLLK; break;
103 
104         case UQQmode:
105         case UHQmode:
106         case USQmode:
107         case UDQmode:
108         case UHAmode:
109         case USAmode:
110         case UDAmode:
111         case UTAmode:
112           warning_at (loc, 0, "using %qs with unsigned type has no effect",
113                       "absfx");
114           return args[0];
115 
116         default:
117           error_at (loc, "no matching fixed-point overload found for %qs",
118                     "absfx");
119 
120           fold = error_mark_node;
121           break;
122         }
123 
124       fold = targetm.builtin_decl (id, true);
125 
126       if (fold != error_mark_node)
127         fold = build_function_call_vec (loc, vNULL, fold, &args, NULL);
128 
129       break; // absfx
130 
131     case AVR_BUILTIN_ROUNDFX:
132       if (args.length() != 2)
133         {
134           error_at (loc, "%qs expects 2 arguments but %d given",
135                     "roundfx", (int) args.length());
136 
137           fold = error_mark_node;
138           break;
139         }
140 
141       type0 = TREE_TYPE (args[0]);
142       type1 = TREE_TYPE (args[1]);
143 
144       if (!FIXED_POINT_TYPE_P (type0))
145         {
146           error_at (loc, "%qs expects a fixed-point value as first argument",
147                     "roundfx");
148 
149           fold = error_mark_node;
150         }
151 
152       if (!INTEGRAL_TYPE_P (type1))
153         {
154           error_at (loc, "%qs expects an integer value as second argument",
155                     "roundfx");
156 
157           fold = error_mark_node;
158         }
159 
160       switch (TYPE_MODE (type0))
161         {
162         case QQmode: id = AVR_BUILTIN_ROUNDHR; break;
163         case HQmode: id = AVR_BUILTIN_ROUNDR; break;
164         case SQmode: id = AVR_BUILTIN_ROUNDLR; break;
165         case DQmode: id = AVR_BUILTIN_ROUNDLLR; break;
166 
167         case UQQmode: id = AVR_BUILTIN_ROUNDUHR; break;
168         case UHQmode: id = AVR_BUILTIN_ROUNDUR; break;
169         case USQmode: id = AVR_BUILTIN_ROUNDULR; break;
170         case UDQmode: id = AVR_BUILTIN_ROUNDULLR; break;
171 
172         case HAmode: id = AVR_BUILTIN_ROUNDHK; break;
173         case SAmode: id = AVR_BUILTIN_ROUNDK; break;
174         case DAmode: id = AVR_BUILTIN_ROUNDLK; break;
175         case TAmode: id = AVR_BUILTIN_ROUNDLLK; break;
176 
177         case UHAmode: id = AVR_BUILTIN_ROUNDUHK; break;
178         case USAmode: id = AVR_BUILTIN_ROUNDUK; break;
179         case UDAmode: id = AVR_BUILTIN_ROUNDULK; break;
180         case UTAmode: id = AVR_BUILTIN_ROUNDULLK; break;
181 
182         default:
183           error_at (loc, "no matching fixed-point overload found for %qs",
184                     "roundfx");
185 
186           fold = error_mark_node;
187           break;
188         }
189 
190       fold = targetm.builtin_decl (id, true);
191 
192       if (fold != error_mark_node)
193         fold = build_function_call_vec (loc, vNULL, fold, &args, NULL);
194 
195       break; // roundfx
196 
197     case AVR_BUILTIN_COUNTLSFX:
198       if (args.length() != 1)
199         {
200           error_at (loc, "%qs expects 1 argument but %d given",
201                     "countlsfx", (int) args.length());
202 
203           fold = error_mark_node;
204           break;
205         }
206 
207       type0 = TREE_TYPE (args[0]);
208 
209       if (!FIXED_POINT_TYPE_P (type0))
210         {
211           error_at (loc, "%qs expects a fixed-point value as first argument",
212                     "countlsfx");
213 
214           fold = error_mark_node;
215         }
216 
217       switch (TYPE_MODE (type0))
218         {
219         case QQmode: id = AVR_BUILTIN_COUNTLSHR; break;
220         case HQmode: id = AVR_BUILTIN_COUNTLSR; break;
221         case SQmode: id = AVR_BUILTIN_COUNTLSLR; break;
222         case DQmode: id = AVR_BUILTIN_COUNTLSLLR; break;
223 
224         case UQQmode: id = AVR_BUILTIN_COUNTLSUHR; break;
225         case UHQmode: id = AVR_BUILTIN_COUNTLSUR; break;
226         case USQmode: id = AVR_BUILTIN_COUNTLSULR; break;
227         case UDQmode: id = AVR_BUILTIN_COUNTLSULLR; break;
228 
229         case HAmode: id = AVR_BUILTIN_COUNTLSHK; break;
230         case SAmode: id = AVR_BUILTIN_COUNTLSK; break;
231         case DAmode: id = AVR_BUILTIN_COUNTLSLK; break;
232         case TAmode: id = AVR_BUILTIN_COUNTLSLLK; break;
233 
234         case UHAmode: id = AVR_BUILTIN_COUNTLSUHK; break;
235         case USAmode: id = AVR_BUILTIN_COUNTLSUK; break;
236         case UDAmode: id = AVR_BUILTIN_COUNTLSULK; break;
237         case UTAmode: id = AVR_BUILTIN_COUNTLSULLK; break;
238 
239         default:
240           error_at (loc, "no matching fixed-point overload found for %qs",
241                     "countlsfx");
242 
243           fold = error_mark_node;
244           break;
245         }
246 
247       fold = targetm.builtin_decl (id, true);
248 
249       if (fold != error_mark_node)
250         fold = build_function_call_vec (loc, vNULL, fold, &args, NULL);
251 
252       break; // countlsfx
253     }
254 
255   return fold;
256 }
257 
258 
259 /* Implement `REGISTER_TARGET_PRAGMAS'.  */
260 
261 void
262 avr_register_target_pragmas (void)
263 {
264   int i;
265 
266   gcc_assert (ADDR_SPACE_GENERIC == ADDR_SPACE_RAM);
267 
268   /* Register address spaces.  The order must be the same as in the respective
269      enum from avr.h (or designated initializers must be used in avr.c).  */
270 
271   for (i = 0; i < ADDR_SPACE_COUNT; i++)
272     {
273       gcc_assert (i == avr_addrspace[i].id);
274 
275       if (!ADDR_SPACE_GENERIC_P (i))
276         c_register_addr_space (avr_addrspace[i].name, avr_addrspace[i].id);
277     }
278 
279   targetm.resolve_overloaded_builtin = avr_resolve_overloaded_builtin;
280 }
281 
282 
283 /* Transform LO into uppercase and write the result to UP.
284    You must provide enough space for UP.  Return UP.  */
285 
286 static char*
287 avr_toupper (char *up, const char *lo)
288 {
289   char *up0 = up;
290 
291   for (; *lo; lo++, up++)
292     *up = TOUPPER (*lo);
293 
294   *up = '\0';
295 
296   return up0;
297 }
298 
299 /* Worker function for TARGET_CPU_CPP_BUILTINS.  */
300 
301 void
302 avr_cpu_cpp_builtins (struct cpp_reader *pfile)
303 {
304   int i;
305 
306   builtin_define_std ("AVR");
307 
308   /* __AVR_DEVICE_NAME__ and  avr_mcu_types[].macro like __AVR_ATmega8__
309 	 are defined by -D command option, see device-specs file.  */
310 
311   if (avr_arch->macro)
312     cpp_define_formatted (pfile, "__AVR_ARCH__=%s", avr_arch->macro);
313   if (AVR_HAVE_RAMPD)    cpp_define (pfile, "__AVR_HAVE_RAMPD__");
314   if (AVR_HAVE_RAMPX)    cpp_define (pfile, "__AVR_HAVE_RAMPX__");
315   if (AVR_HAVE_RAMPY)    cpp_define (pfile, "__AVR_HAVE_RAMPY__");
316   if (AVR_HAVE_RAMPZ)    cpp_define (pfile, "__AVR_HAVE_RAMPZ__");
317   if (AVR_HAVE_ELPM)     cpp_define (pfile, "__AVR_HAVE_ELPM__");
318   if (AVR_HAVE_ELPMX)    cpp_define (pfile, "__AVR_HAVE_ELPMX__");
319   if (AVR_HAVE_MOVW)     cpp_define (pfile, "__AVR_HAVE_MOVW__");
320   if (AVR_HAVE_LPMX)     cpp_define (pfile, "__AVR_HAVE_LPMX__");
321 
322   if (avr_arch->asm_only)
323     cpp_define (pfile, "__AVR_ASM_ONLY__");
324   if (AVR_HAVE_MUL)
325     {
326       cpp_define (pfile, "__AVR_ENHANCED__");
327       cpp_define (pfile, "__AVR_HAVE_MUL__");
328     }
329   if (avr_arch->have_jmp_call)
330     {
331       cpp_define (pfile, "__AVR_MEGA__");
332       cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
333     }
334   if (AVR_XMEGA)
335     cpp_define (pfile, "__AVR_XMEGA__");
336 
337   if (AVR_TINY)
338     {
339       cpp_define (pfile, "__AVR_TINY__");
340 
341       /* Define macro "__AVR_TINY_PM_BASE_ADDRESS__" with mapped program memory
342          start address.  This macro shall be used where mapped program
343          memory is accessed, eg. copying data section (__do_copy_data)
344          contents to data memory region.
345          NOTE:
346          Program memory of AVR_TINY devices cannot be accessed directly,
347          it has been mapped to the data memory.  For AVR_TINY devices
348          (ATtiny4/5/9/10/20 and 40) mapped program memory starts at 0x4000. */
349 
350       cpp_define (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x4000");
351     }
352 
353   if (AVR_HAVE_EIJMP_EICALL)
354     {
355       cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
356       cpp_define (pfile, "__AVR_3_BYTE_PC__");
357     }
358   else
359     {
360       cpp_define (pfile, "__AVR_2_BYTE_PC__");
361     }
362 
363   if (AVR_HAVE_8BIT_SP)
364     cpp_define (pfile, "__AVR_HAVE_8BIT_SP__");
365   else
366     cpp_define (pfile, "__AVR_HAVE_16BIT_SP__");
367 
368   if (AVR_HAVE_SPH)
369     cpp_define (pfile, "__AVR_HAVE_SPH__");
370   else
371     cpp_define (pfile, "__AVR_SP8__");
372 
373   if (TARGET_NO_INTERRUPTS)
374     cpp_define (pfile, "__NO_INTERRUPTS__");
375 
376   if (TARGET_SKIP_BUG)
377     {
378       cpp_define (pfile, "__AVR_ERRATA_SKIP__");
379 
380       if (AVR_HAVE_JMP_CALL)
381         cpp_define (pfile, "__AVR_ERRATA_SKIP_JMP_CALL__");
382     }
383 
384   if (TARGET_RMW)
385     cpp_define (pfile, "__AVR_ISA_RMW__");
386 
387   cpp_define_formatted (pfile, "__AVR_SFR_OFFSET__=0x%x",
388                         avr_arch->sfr_offset);
389 
390 #ifdef WITH_AVRLIBC
391   cpp_define (pfile, "__WITH_AVRLIBC__");
392 #endif /* WITH_AVRLIBC */
393 
394   /* Define builtin macros so that the user can easily query whether
395      non-generic address spaces (and which) are supported or not.
396      This is only supported for C.  For C++, a language extension is needed
397      (as mentioned in ISO/IEC DTR 18037; Annex F.2) which is not
398      implemented in GCC up to now.  */
399 
400   if (lang_GNU_C ())
401     {
402       for (i = 0; i < ADDR_SPACE_COUNT; i++)
403         if (!ADDR_SPACE_GENERIC_P (i)
404             /* Only supply __FLASH<n> macro if the address space is reasonable
405                for this target.  The address space qualifier itself is still
406                supported, but using it will throw an error.  */
407             && avr_addrspace[i].segment < avr_n_flash
408 	    /* Only support __MEMX macro if we have LPM.  */
409 	    && (AVR_HAVE_LPM || avr_addrspace[i].pointer_size <= 2))
410 
411           {
412             const char *name = avr_addrspace[i].name;
413             char *Name = (char*) alloca (1 + strlen (name));
414 
415             cpp_define (pfile, avr_toupper (Name, name));
416           }
417     }
418 
419   /* Define builtin macros so that the user can easily query whether or
420      not a specific builtin is available. */
421 
422 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)  \
423   cpp_define (pfile, "__BUILTIN_AVR_" #NAME);
424 #include "builtins.def"
425 #undef DEF_BUILTIN
426 
427   /* Builtin macros for the __int24 and __uint24 type.  */
428 
429   cpp_define_formatted (pfile, "__INT24_MAX__=8388607%s",
430                         INT_TYPE_SIZE == 8 ? "LL" : "L");
431   cpp_define (pfile, "__INT24_MIN__=(-__INT24_MAX__-1)");
432   cpp_define_formatted (pfile, "__UINT24_MAX__=16777215%s",
433                         INT_TYPE_SIZE == 8 ? "ULL" : "UL");
434 }
435