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