1 /* Copyright (C) 2009-2019 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 #define IN_TARGET_CODE 1
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "target.h"
28 #include "c-family/c-common.h"
29 #include "stor-layout.h"
30 #include "langhooks.h"
31 #include "memmodel.h"
32 #include "tm_p.h"
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
avr_resolve_overloaded_builtin(unsigned int iloc,tree fndecl,void * vargs)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 E_QQmode: id = AVR_BUILTIN_ABSHR; break;
85 case E_HQmode: id = AVR_BUILTIN_ABSR; break;
86 case E_SQmode: id = AVR_BUILTIN_ABSLR; break;
87 case E_DQmode: id = AVR_BUILTIN_ABSLLR; break;
88
89 case E_HAmode: id = AVR_BUILTIN_ABSHK; break;
90 case E_SAmode: id = AVR_BUILTIN_ABSK; break;
91 case E_DAmode: id = AVR_BUILTIN_ABSLK; break;
92 case E_TAmode: id = AVR_BUILTIN_ABSLLK; break;
93
94 case E_UQQmode:
95 case E_UHQmode:
96 case E_USQmode:
97 case E_UDQmode:
98 case E_UHAmode:
99 case E_USAmode:
100 case E_UDAmode:
101 case E_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, vNULL, 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 E_QQmode: id = AVR_BUILTIN_ROUNDHR; break;
153 case E_HQmode: id = AVR_BUILTIN_ROUNDR; break;
154 case E_SQmode: id = AVR_BUILTIN_ROUNDLR; break;
155 case E_DQmode: id = AVR_BUILTIN_ROUNDLLR; break;
156
157 case E_UQQmode: id = AVR_BUILTIN_ROUNDUHR; break;
158 case E_UHQmode: id = AVR_BUILTIN_ROUNDUR; break;
159 case E_USQmode: id = AVR_BUILTIN_ROUNDULR; break;
160 case E_UDQmode: id = AVR_BUILTIN_ROUNDULLR; break;
161
162 case E_HAmode: id = AVR_BUILTIN_ROUNDHK; break;
163 case E_SAmode: id = AVR_BUILTIN_ROUNDK; break;
164 case E_DAmode: id = AVR_BUILTIN_ROUNDLK; break;
165 case E_TAmode: id = AVR_BUILTIN_ROUNDLLK; break;
166
167 case E_UHAmode: id = AVR_BUILTIN_ROUNDUHK; break;
168 case E_USAmode: id = AVR_BUILTIN_ROUNDUK; break;
169 case E_UDAmode: id = AVR_BUILTIN_ROUNDULK; break;
170 case E_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, vNULL, 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 E_QQmode: id = AVR_BUILTIN_COUNTLSHR; break;
210 case E_HQmode: id = AVR_BUILTIN_COUNTLSR; break;
211 case E_SQmode: id = AVR_BUILTIN_COUNTLSLR; break;
212 case E_DQmode: id = AVR_BUILTIN_COUNTLSLLR; break;
213
214 case E_UQQmode: id = AVR_BUILTIN_COUNTLSUHR; break;
215 case E_UHQmode: id = AVR_BUILTIN_COUNTLSUR; break;
216 case E_USQmode: id = AVR_BUILTIN_COUNTLSULR; break;
217 case E_UDQmode: id = AVR_BUILTIN_COUNTLSULLR; break;
218
219 case E_HAmode: id = AVR_BUILTIN_COUNTLSHK; break;
220 case E_SAmode: id = AVR_BUILTIN_COUNTLSK; break;
221 case E_DAmode: id = AVR_BUILTIN_COUNTLSLK; break;
222 case E_TAmode: id = AVR_BUILTIN_COUNTLSLLK; break;
223
224 case E_UHAmode: id = AVR_BUILTIN_COUNTLSUHK; break;
225 case E_USAmode: id = AVR_BUILTIN_COUNTLSUK; break;
226 case E_UDAmode: id = AVR_BUILTIN_COUNTLSULK; break;
227 case E_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, vNULL, fold, &args, NULL);
241
242 break; // countlsfx
243 }
244
245 return fold;
246 }
247
248
249 /* Implement `REGISTER_TARGET_PRAGMAS'. */
250
251 void
avr_register_target_pragmas(void)252 avr_register_target_pragmas (void)
253 {
254 gcc_assert (ADDR_SPACE_GENERIC == ADDR_SPACE_RAM);
255
256 /* Register address spaces. The order must be the same as in the respective
257 enum from avr.h (or designated initializers must be used in avr.c).
258 We always register all address spaces even if some of them make no
259 sense for some targets. Diagnose for non-supported spaces will be
260 emit by TARGET_ADDR_SPACE_DIAGNOSE_USAGE. */
261
262 for (int i = 0; i < ADDR_SPACE_COUNT; i++)
263 {
264 gcc_assert (i == avr_addrspace[i].id);
265
266 if (!ADDR_SPACE_GENERIC_P (i))
267 c_register_addr_space (avr_addrspace[i].name, avr_addrspace[i].id);
268 }
269
270 targetm.resolve_overloaded_builtin = avr_resolve_overloaded_builtin;
271 }
272
273
274 /* Transform LO into uppercase and write the result to UP.
275 You must provide enough space for UP. Return UP. */
276
277 static char*
avr_toupper(char * up,const char * lo)278 avr_toupper (char *up, const char *lo)
279 {
280 char *up0 = up;
281
282 for (; *lo; lo++, up++)
283 *up = TOUPPER (*lo);
284
285 *up = '\0';
286
287 return up0;
288 }
289
290 /* Worker function for TARGET_CPU_CPP_BUILTINS. */
291
292 void
avr_cpu_cpp_builtins(struct cpp_reader * pfile)293 avr_cpu_cpp_builtins (struct cpp_reader *pfile)
294 {
295 builtin_define_std ("AVR");
296
297 /* __AVR_DEVICE_NAME__ and avr_mcu_types[].macro like __AVR_ATmega8__
298 are defined by -D command option, see device-specs file. */
299
300 if (avr_arch->macro)
301 cpp_define_formatted (pfile, "__AVR_ARCH__=%s", avr_arch->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_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
319 if (AVR_HAVE_JMP_CALL)
320 cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
321
322 if (avr_arch->have_jmp_call)
323 cpp_define (pfile, "__AVR_MEGA__");
324
325 if (AVR_SHORT_CALLS)
326 cpp_define (pfile, "__AVR_SHORT_CALLS__");
327
328 if (AVR_XMEGA)
329 cpp_define (pfile, "__AVR_XMEGA__");
330
331 if (AVR_TINY)
332 {
333 cpp_define (pfile, "__AVR_TINY__");
334
335 /* Define macro "__AVR_TINY_PM_BASE_ADDRESS__" with mapped program memory
336 start address. This macro shall be used where mapped program
337 memory is accessed, eg. copying data section (__do_copy_data)
338 contents to data memory region.
339 NOTE:
340 Program memory of AVR_TINY devices cannot be accessed directly,
341 it has been mapped to the data memory. For AVR_TINY devices
342 (ATtiny4/5/9/10/20 and 40) mapped program memory starts at 0x4000. */
343
344 cpp_define_formatted (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x%x",
345 avr_arch->flash_pm_offset);
346 }
347
348 if (avr_arch->flash_pm_offset)
349 cpp_define_formatted (pfile, "__AVR_PM_BASE_ADDRESS__=0x%x",
350 avr_arch->flash_pm_offset);
351
352 if (AVR_HAVE_EIJMP_EICALL)
353 {
354 cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
355 cpp_define (pfile, "__AVR_3_BYTE_PC__");
356 }
357 else
358 {
359 cpp_define (pfile, "__AVR_2_BYTE_PC__");
360 }
361
362 if (AVR_HAVE_8BIT_SP)
363 cpp_define (pfile, "__AVR_HAVE_8BIT_SP__");
364 else
365 cpp_define (pfile, "__AVR_HAVE_16BIT_SP__");
366
367 if (AVR_HAVE_SPH)
368 cpp_define (pfile, "__AVR_HAVE_SPH__");
369 else
370 cpp_define (pfile, "__AVR_SP8__");
371
372 if (TARGET_NO_INTERRUPTS)
373 cpp_define (pfile, "__NO_INTERRUPTS__");
374
375 if (TARGET_SKIP_BUG)
376 {
377 cpp_define (pfile, "__AVR_ERRATA_SKIP__");
378
379 if (AVR_HAVE_JMP_CALL)
380 cpp_define (pfile, "__AVR_ERRATA_SKIP_JMP_CALL__");
381 }
382
383 if (TARGET_RMW)
384 cpp_define (pfile, "__AVR_ISA_RMW__");
385
386 cpp_define_formatted (pfile, "__AVR_SFR_OFFSET__=0x%x",
387 avr_arch->sfr_offset);
388
389 #ifdef WITH_AVRLIBC
390 cpp_define (pfile, "__WITH_AVRLIBC__");
391 #endif /* WITH_AVRLIBC */
392
393 /* Define builtin macros so that the user can easily query whether
394 non-generic address spaces (and which) are supported or not.
395 This is only supported for C. For C++, a language extension is needed
396 (as mentioned in ISO/IEC DTR 18037; Annex F.2) which is not
397 implemented in GCC up to now. */
398
399 if (lang_GNU_C ())
400 {
401 for (int i = 0; i < ADDR_SPACE_COUNT; i++)
402 if (!ADDR_SPACE_GENERIC_P (i)
403 /* Only supply __FLASH<n> macro if the address space is reasonable
404 for this target. The address space qualifier itself is still
405 supported, but using it will throw an error. */
406 && avr_addr_space_supported_p ((addr_space_t) i))
407 {
408 const char *name = avr_addrspace[i].name;
409 char *Name = (char*) alloca (1 + strlen (name));
410
411 cpp_define (pfile, avr_toupper (Name, name));
412 }
413 }
414
415 /* Define builtin macros so that the user can easily query whether or
416 not a specific builtin is available. */
417
418 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
419 cpp_define (pfile, "__BUILTIN_AVR_" #NAME);
420 #include "builtins.def"
421 #undef DEF_BUILTIN
422
423 /* Builtin macros for the __int24 and __uint24 type. */
424
425 cpp_define_formatted (pfile, "__INT24_MAX__=8388607%s",
426 INT_TYPE_SIZE == 8 ? "LL" : "L");
427 cpp_define (pfile, "__INT24_MIN__=(-__INT24_MAX__-1)");
428 cpp_define_formatted (pfile, "__UINT24_MAX__=16777215%s",
429 INT_TYPE_SIZE == 8 ? "ULL" : "UL");
430 }
431