comparison gcc/config/avr/avr.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers 1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998-2017 Free Software Foundation, Inc. 2 Copyright (C) 1998-2018 Free Software Foundation, Inc.
3 Contributed by Denis Chertykov (chertykov@gmail.com) 3 Contributed by Denis Chertykov (chertykov@gmail.com)
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify 7 GCC is free software; you can redistribute it and/or modify
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see 18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */ 19 <http://www.gnu.org/licenses/>. */
20
21 #define IN_TARGET_CODE 1
20 22
21 #include "config.h" 23 #include "config.h"
22 #include "system.h" 24 #include "system.h"
23 #include "intl.h" 25 #include "intl.h"
24 #include "coretypes.h" 26 #include "coretypes.h"
61 63
62 /* Maximal allowed offset for an address in the LD command */ 64 /* Maximal allowed offset for an address in the LD command */
63 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE)) 65 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
64 66
65 /* Return true if STR starts with PREFIX and false, otherwise. */ 67 /* Return true if STR starts with PREFIX and false, otherwise. */
66 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX))) 68 #define STR_PREFIX_P(STR,PREFIX) (strncmp (STR, PREFIX, strlen (PREFIX)) == 0)
67 69
68 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the 70 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
69 address space where data is to be located. 71 address space where data is to be located.
70 As the only non-generic address spaces are all located in flash, 72 As the only non-generic address spaces are all located in flash,
71 this can be used to test if data shall go into some .progmem* section. 73 this can be used to test if data shall go into some .progmem* section.
265 for (int i = 0; i < n_bytes; i++) 267 for (int i = 0; i < n_bytes; i++)
266 { 268 {
267 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i); 269 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
268 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode); 270 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
269 271
270 if (0 == (pop_mask & (1 << popcount_hwi (val8)))) 272 if ((pop_mask & (1 << popcount_hwi (val8))) == 0)
271 return false; 273 return false;
272 } 274 }
273 275
274 return true; 276 return true;
275 } 277 }
457 459
458 extract_insn (xinsn); 460 extract_insn (xinsn);
459 461
460 // Assert on the anatomy of xinsn's operands we are going to work with. 462 // Assert on the anatomy of xinsn's operands we are going to work with.
461 463
462 gcc_assert (11 == recog_data.n_operands); 464 gcc_assert (recog_data.n_operands == 11);
463 gcc_assert (4 == recog_data.n_dups); 465 gcc_assert (recog_data.n_dups == 4);
464 466
465 if (dump_file) 467 if (dump_file)
466 { 468 {
467 fprintf (dump_file, ";; Operands extracted:\n"); 469 fprintf (dump_file, ";; Operands extracted:\n");
468 for (int i = 0; i < recog_data.n_operands; i++) 470 for (int i = 0; i < recog_data.n_operands; i++)
505 sub_5 = XEXP (xop[6], 0); 507 sub_5 = XEXP (xop[6], 0);
506 } 508 }
507 509
508 if (sub_5 510 if (sub_5
509 && SUBREG_P (sub_5) 511 && SUBREG_P (sub_5)
510 && 0 == SUBREG_BYTE (sub_5) 512 && SUBREG_BYTE (sub_5) == 0
511 && rtx_equal_p (xop[5], SUBREG_REG (sub_5))) 513 && rtx_equal_p (xop[5], SUBREG_REG (sub_5)))
512 return true; 514 return true;
513 515
514 if (dump_file) 516 if (dump_file)
515 fprintf (dump_file, "\n;; Failed condition for casesi_<mode>_sequence\n\n"); 517 fprintf (dump_file, "\n;; Failed condition for casesi_<mode>_sequence\n\n");
693 695
694 avr_arch = &avr_arch_types[0]; 696 avr_arch = &avr_arch_types[0];
695 697
696 for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++) 698 for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++)
697 { 699 {
698 if (NULL == mcu->name) 700 if (mcu->name == NULL)
699 { 701 {
700 /* Reached the end of `avr_mcu_types'. This should actually never 702 /* Reached the end of `avr_mcu_types'. This should actually never
701 happen as options are provided by device-specs. It could be a 703 happen as options are provided by device-specs. It could be a
702 typo in a device-specs or calling the compiler proper directly 704 typo in a device-specs or calling the compiler proper directly
703 with -mmcu=<device>. */ 705 with -mmcu=<device>. */
705 error ("unknown core architecture %qs specified with %qs", 707 error ("unknown core architecture %qs specified with %qs",
706 avr_mmcu, "-mmcu="); 708 avr_mmcu, "-mmcu=");
707 avr_inform_core_architectures (); 709 avr_inform_core_architectures ();
708 break; 710 break;
709 } 711 }
710 else if (0 == strcmp (mcu->name, avr_mmcu) 712 else if (strcmp (mcu->name, avr_mmcu) == 0
711 // Is this a proper architecture ? 713 // Is this a proper architecture ?
712 && NULL == mcu->macro) 714 && mcu->macro == NULL)
713 { 715 {
714 avr_arch = &avr_arch_types[mcu->arch_id]; 716 avr_arch = &avr_arch_types[mcu->arch_id];
715 if (avr_n_flash < 0) 717 if (avr_n_flash < 0)
716 avr_n_flash = 1 + (mcu->flash_size - 1) / 0x10000; 718 avr_n_flash = 1 + (mcu->flash_size - 1) / 0x10000;
717 719
726 /* Implement `TARGET_OPTION_OVERRIDE'. */ 728 /* Implement `TARGET_OPTION_OVERRIDE'. */
727 729
728 static void 730 static void
729 avr_option_override (void) 731 avr_option_override (void)
730 { 732 {
731 /* Disable -fdelete-null-pointer-checks option for AVR target.
732 This option compiler assumes that dereferencing of a null pointer
733 would halt the program. For AVR this assumption is not true and
734 programs can safely dereference null pointers. Changes made by this
735 option may not work properly for AVR. So disable this option. */
736
737 flag_delete_null_pointer_checks = 0;
738
739 /* caller-save.c looks for call-clobbered hard registers that are assigned 733 /* caller-save.c looks for call-clobbered hard registers that are assigned
740 to pseudos that cross calls and tries so save-restore them around calls 734 to pseudos that cross calls and tries so save-restore them around calls
741 in order to reduce the number of stack slots needed. 735 in order to reduce the number of stack slots needed.
742 736
743 This might lead to situations where reload is no more able to cope 737 This might lead to situations where reload is no more able to cope
1026 /* Sanity cheching for above function attributes. */ 1020 /* Sanity cheching for above function attributes. */
1027 1021
1028 static void 1022 static void
1029 avr_set_current_function (tree decl) 1023 avr_set_current_function (tree decl)
1030 { 1024 {
1031 location_t loc;
1032 const char *isr;
1033
1034 if (decl == NULL_TREE 1025 if (decl == NULL_TREE
1035 || current_function_decl == NULL_TREE 1026 || current_function_decl == NULL_TREE
1036 || current_function_decl == error_mark_node 1027 || current_function_decl == error_mark_node
1037 || ! cfun->machine 1028 || ! cfun->machine
1038 || cfun->machine->attributes_checked_p) 1029 || cfun->machine->attributes_checked_p)
1039 return; 1030 return;
1040 1031
1041 loc = DECL_SOURCE_LOCATION (decl); 1032 location_t loc = DECL_SOURCE_LOCATION (decl);
1042 1033
1043 cfun->machine->is_naked = avr_naked_function_p (decl); 1034 cfun->machine->is_naked = avr_naked_function_p (decl);
1044 cfun->machine->is_signal = avr_signal_function_p (decl); 1035 cfun->machine->is_signal = avr_signal_function_p (decl);
1045 cfun->machine->is_interrupt = avr_interrupt_function_p (decl); 1036 cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
1046 cfun->machine->is_OS_task = avr_OS_task_function_p (decl); 1037 cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
1047 cfun->machine->is_OS_main = avr_OS_main_function_p (decl); 1038 cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
1048 cfun->machine->is_no_gccisr = avr_no_gccisr_function_p (decl); 1039 cfun->machine->is_no_gccisr = avr_no_gccisr_function_p (decl);
1049 1040
1050 isr = cfun->machine->is_interrupt ? "interrupt" : "signal"; 1041 const char *isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
1051 1042
1052 /* Too much attributes make no sense as they request conflicting features. */ 1043 /* Too much attributes make no sense as they request conflicting features. */
1053 1044
1054 if (cfun->machine->is_OS_task + cfun->machine->is_OS_main 1045 if (cfun->machine->is_OS_task
1055 + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1) 1046 && (cfun->machine->is_signal || cfun->machine->is_interrupt))
1056 error_at (loc, "function attributes %qs, %qs and %qs are mutually" 1047 error_at (loc, "function attributes %qs and %qs are mutually exclusive",
1057 " exclusive", "OS_task", "OS_main", isr); 1048 "OS_task", isr);
1058 1049
1059 /* 'naked' will hide effects of 'OS_task' and 'OS_main'. */ 1050 if (cfun->machine->is_OS_main
1060 1051 && (cfun->machine->is_signal || cfun->machine->is_interrupt))
1061 if (cfun->machine->is_naked 1052 error_at (loc, "function attributes %qs and %qs are mutually exclusive",
1062 && (cfun->machine->is_OS_task || cfun->machine->is_OS_main)) 1053 "OS_main", isr);
1063 warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
1064 " no effect on %qs function", "OS_task", "OS_main", "naked");
1065 1054
1066 if (cfun->machine->is_interrupt || cfun->machine->is_signal) 1055 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1067 { 1056 {
1068 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl)); 1057 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
1069 tree ret = TREE_TYPE (TREE_TYPE (decl)); 1058 tree ret = TREE_TYPE (TREE_TYPE (decl));
1105 1094
1106 #if defined WITH_AVRLIBC 1095 #if defined WITH_AVRLIBC
1107 // Common problem is using "ISR" without first including avr/interrupt.h. 1096 // Common problem is using "ISR" without first including avr/interrupt.h.
1108 const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); 1097 const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
1109 name = default_strip_name_encoding (name); 1098 name = default_strip_name_encoding (name);
1110 if (0 == strcmp ("ISR", name) 1099 if (strcmp ("ISR", name) == 0
1111 || 0 == strcmp ("INTERRUPT", name) 1100 || strcmp ("INTERRUPT", name) == 0
1112 || 0 == strcmp ("SIGNAL", name)) 1101 || strcmp ("SIGNAL", name) == 0)
1113 { 1102 {
1114 warning_at (loc, OPT_Wmisspelled_isr, "%qs is a reserved identifier" 1103 warning_at (loc, OPT_Wmisspelled_isr, "%qs is a reserved identifier"
1115 " in AVR-LibC. Consider %<#include <avr/interrupt.h>%>" 1104 " in AVR-LibC. Consider %<#include <avr/interrupt.h>%>"
1116 " before using the %qs macro", name, name); 1105 " before using the %qs macro", name, name);
1117 } 1106 }
1147 /* Report contribution of accumulated outgoing arguments to stack size. */ 1136 /* Report contribution of accumulated outgoing arguments to stack size. */
1148 1137
1149 static inline int 1138 static inline int
1150 avr_outgoing_args_size (void) 1139 avr_outgoing_args_size (void)
1151 { 1140 {
1152 return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0; 1141 return (ACCUMULATE_OUTGOING_ARGS
1142 ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0);
1153 } 1143 }
1154 1144
1155 1145
1156 /* Implement TARGET_STARTING_FRAME_OFFSET. */ 1146 /* Implement TARGET_STARTING_FRAME_OFFSET. */
1157 /* This is the offset from the frame pointer register to the first stack slot 1147 /* This is the offset from the frame pointer register to the first stack slot
2040 if (ACCUMULATE_OUTGOING_ARGS) 2030 if (ACCUMULATE_OUTGOING_ARGS)
2041 fprintf (file, "/* outgoing args size = %d */\n", 2031 fprintf (file, "/* outgoing args size = %d */\n",
2042 avr_outgoing_args_size()); 2032 avr_outgoing_args_size());
2043 2033
2044 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n", 2034 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
2045 get_frame_size()); 2035 (HOST_WIDE_INT) get_frame_size());
2046 2036
2047 if (!cfun->machine->gasisr.yes) 2037 if (!cfun->machine->gasisr.yes)
2048 { 2038 {
2049 fprintf (file, "/* stack size = %d */\n", cfun->machine->stack_usage); 2039 fprintf (file, "/* stack size = %d */\n", cfun->machine->stack_usage);
2050 // Create symbol stack offset so all functions have it. Add 1 to stack 2040 // Create symbol stack offset so all functions have it. Add 1 to stack
2568 return x; 2558 return x;
2569 } 2559 }
2570 2560
2571 if (GET_CODE (x) == PLUS 2561 if (GET_CODE (x) == PLUS
2572 && REG_P (XEXP (x, 0)) 2562 && REG_P (XEXP (x, 0))
2573 && 0 == reg_equiv_constant (REGNO (XEXP (x, 0))) 2563 && reg_equiv_constant (REGNO (XEXP (x, 0))) == 0
2574 && CONST_INT_P (XEXP (x, 1)) 2564 && CONST_INT_P (XEXP (x, 1))
2575 && INTVAL (XEXP (x, 1)) >= 1) 2565 && INTVAL (XEXP (x, 1)) >= 1)
2576 { 2566 {
2577 bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode); 2567 bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
2578 2568
2635 */ 2625 */
2636 2626
2637 static const char* 2627 static const char*
2638 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words) 2628 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
2639 { 2629 {
2640 if (NULL == plen) 2630 if (plen == NULL)
2641 { 2631 output_asm_insn (tpl, operands);
2642 output_asm_insn (tpl, operands);
2643 }
2644 else 2632 else
2645 { 2633 {
2646 if (n_words < 0) 2634 if (n_words < 0)
2647 *plen = -n_words; 2635 *plen = -n_words;
2648 else 2636 else
2965 fatal_insn ("bad address, not an I/O address:", x); 2953 fatal_insn ("bad address, not an I/O address:", x);
2966 } 2954 }
2967 else if (code == 'x') 2955 else if (code == 'x')
2968 { 2956 {
2969 /* Constant progmem address - like used in jmp or call */ 2957 /* Constant progmem address - like used in jmp or call */
2970 if (0 == text_segment_operand (x, VOIDmode)) 2958 if (text_segment_operand (x, VOIDmode) == 0)
2971 if (warning (0, "accessing program memory" 2959 if (warning (0, "accessing program memory"
2972 " with data memory address")) 2960 " with data memory address"))
2973 { 2961 {
2974 output_addr_const (stderr, x); 2962 output_addr_const (stderr, x);
2975 fprintf(stderr,"\n"); 2963 fprintf(stderr,"\n");
3523 /* Ensure that caller and callee have compatible epilogues */ 3511 /* Ensure that caller and callee have compatible epilogues */
3524 3512
3525 if (cfun->machine->is_interrupt 3513 if (cfun->machine->is_interrupt
3526 || cfun->machine->is_signal 3514 || cfun->machine->is_signal
3527 || cfun->machine->is_naked 3515 || cfun->machine->is_naked
3528 || avr_naked_function_p (decl_callee) 3516 || avr_naked_function_p (decl_callee))
3529 /* FIXME: For OS_task and OS_main, this might be over-conservative. */
3530 || (avr_OS_task_function_p (decl_callee)
3531 != cfun->machine->is_OS_task)
3532 || (avr_OS_main_function_p (decl_callee)
3533 != cfun->machine->is_OS_main))
3534 { 3517 {
3535 return false; 3518 return false;
3536 } 3519 }
3537 3520
3538 return true; 3521 return true;
3926 || avr_mem_flash_p (dest)) 3909 || avr_mem_flash_p (dest))
3927 { 3910 {
3928 return avr_out_lpm (insn, operands, plen); 3911 return avr_out_lpm (insn, operands, plen);
3929 } 3912 }
3930 3913
3931 gcc_assert (1 == GET_MODE_SIZE (GET_MODE (dest))); 3914 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 1);
3932 3915
3933 if (REG_P (dest)) 3916 if (REG_P (dest))
3934 { 3917 {
3935 if (REG_P (src)) /* mov r,r */ 3918 if (REG_P (src)) /* mov r,r */
3936 { 3919 {
4921 } 4904 }
4922 4905
4923 if (!l) 4906 if (!l)
4924 l = &dummy; 4907 l = &dummy;
4925 4908
4926 gcc_assert (4 == GET_MODE_SIZE (GET_MODE (dest))); 4909 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 4);
4927 4910
4928 if (REG_P (dest)) 4911 if (REG_P (dest))
4929 { 4912 {
4930 if (REG_P (src)) /* mov r,r */ 4913 if (REG_P (src)) /* mov r,r */
4931 { 4914 {
8261 { 8244 {
8262 avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label); 8245 avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label);
8263 return ""; 8246 return "";
8264 } 8247 }
8265 8248
8266 if (8 == n_bytes) 8249 if (n_bytes == 8)
8267 { 8250 {
8268 op[0] = gen_rtx_REG (DImode, ACC_A); 8251 op[0] = gen_rtx_REG (DImode, ACC_A);
8269 op[1] = gen_rtx_REG (DImode, ACC_A); 8252 op[1] = gen_rtx_REG (DImode, ACC_A);
8270 op[2] = avr_to_int_mode (xop[0]); 8253 op[2] = avr_to_int_mode (xop[0]);
8271 } 8254 }
8379 8362
8380 switch (code) 8363 switch (code)
8381 { 8364 {
8382 case IOR: 8365 case IOR:
8383 8366
8384 if (0 == pop8) 8367 if (pop8 == 0)
8385 continue; 8368 continue;
8386 else if (ld_reg_p) 8369 else if (ld_reg_p)
8387 avr_asm_len ("ori %0,%1", op, plen, 1); 8370 avr_asm_len ("ori %0,%1", op, plen, 1);
8388 else if (1 == pop8) 8371 else if (pop8 == 1)
8389 { 8372 {
8390 if (set_t != 1) 8373 if (set_t != 1)
8391 avr_asm_len ("set", op, plen, 1); 8374 avr_asm_len ("set", op, plen, 1);
8392 set_t = 1; 8375 set_t = 1;
8393 8376
8394 op[1] = GEN_INT (exact_log2 (val8)); 8377 op[1] = GEN_INT (exact_log2 (val8));
8395 avr_asm_len ("bld %0,%1", op, plen, 1); 8378 avr_asm_len ("bld %0,%1", op, plen, 1);
8396 } 8379 }
8397 else if (8 == pop8) 8380 else if (pop8 == 8)
8398 { 8381 {
8399 if (op[3] != NULL_RTX) 8382 if (op[3] != NULL_RTX)
8400 avr_asm_len ("mov %0,%3", op, plen, 1); 8383 avr_asm_len ("mov %0,%3", op, plen, 1);
8401 else 8384 else
8402 avr_asm_len ("clr %0" CR_TAB 8385 avr_asm_len ("clr %0" CR_TAB
8415 8398
8416 continue; /* IOR */ 8399 continue; /* IOR */
8417 8400
8418 case AND: 8401 case AND:
8419 8402
8420 if (8 == pop8) 8403 if (pop8 == 8)
8421 continue; 8404 continue;
8422 else if (0 == pop8) 8405 else if (pop8 == 0)
8423 avr_asm_len ("clr %0", op, plen, 1); 8406 avr_asm_len ("clr %0", op, plen, 1);
8424 else if (ld_reg_p) 8407 else if (ld_reg_p)
8425 avr_asm_len ("andi %0,%1", op, plen, 1); 8408 avr_asm_len ("andi %0,%1", op, plen, 1);
8426 else if (7 == pop8) 8409 else if (pop8 == 7)
8427 { 8410 {
8428 if (set_t != 0) 8411 if (set_t != 0)
8429 avr_asm_len ("clt", op, plen, 1); 8412 avr_asm_len ("clt", op, plen, 1);
8430 set_t = 0; 8413 set_t = 0;
8431 8414
8443 8426
8444 continue; /* AND */ 8427 continue; /* AND */
8445 8428
8446 case XOR: 8429 case XOR:
8447 8430
8448 if (0 == pop8) 8431 if (pop8 == 0)
8449 continue; 8432 continue;
8450 else if (8 == pop8) 8433 else if (pop8 == 8)
8451 avr_asm_len ("com %0", op, plen, 1); 8434 avr_asm_len ("com %0", op, plen, 1);
8452 else if (ld_reg_p && val8 == (1 << 7)) 8435 else if (ld_reg_p && val8 == (1 << 7))
8453 avr_asm_len ("subi %0,%1", op, plen, 1); 8436 avr_asm_len ("subi %0,%1", op, plen, 1);
8454 else 8437 else
8455 { 8438 {
8723 // Do we have a 16-Bit register that is cleared? 8706 // Do we have a 16-Bit register that is cleared?
8724 rtx clrw = NULL_RTX; 8707 rtx clrw = NULL_RTX;
8725 8708
8726 bool sign_extend = src.sbit && sign_bytes; 8709 bool sign_extend = src.sbit && sign_bytes;
8727 8710
8728 if (0 == dest.fbit % 8 && 7 == src.fbit % 8) 8711 if (dest.fbit % 8 == 0 && src.fbit % 8 == 7)
8729 shift = ASHIFT; 8712 shift = ASHIFT;
8730 else if (7 == dest.fbit % 8 && 0 == src.fbit % 8) 8713 else if (dest.fbit % 8 == 7 && src.fbit % 8 == 0)
8731 shift = ASHIFTRT; 8714 shift = ASHIFTRT;
8732 else if (dest.fbit % 8 == src.fbit % 8) 8715 else if (dest.fbit % 8 == src.fbit % 8)
8733 shift = UNKNOWN; 8716 shift = UNKNOWN;
8734 else 8717 else
8735 gcc_unreachable(); 8718 gcc_unreachable();
9397 /* Some complex insns don't need length adjustment and therefore 9380 /* Some complex insns don't need length adjustment and therefore
9398 the length need not/must not be adjusted for these insns. 9381 the length need not/must not be adjusted for these insns.
9399 It is easier to state this in an insn attribute "adjust_len" than 9382 It is easier to state this in an insn attribute "adjust_len" than
9400 to clutter up code here... */ 9383 to clutter up code here... */
9401 9384
9402 if (!NONDEBUG_INSN_P (insn) 9385 if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) == -1)
9403 || -1 == recog_memoized (insn))
9404 { 9386 {
9405 return len; 9387 return len;
9406 } 9388 }
9407 9389
9408 /* Read from insn attribute "adjust_len" if/how length is to be adjusted. */ 9390 /* Read from insn attribute "adjust_len" if/how length is to be adjusted. */
9869 return x; 9851 return x;
9870 } 9852 }
9871 9853
9872 9854
9873 /* AVR attributes. */ 9855 /* AVR attributes. */
9874 static const struct attribute_spec 9856 static const struct attribute_spec avr_attribute_table[] =
9875 avr_attribute_table[] = 9857 {
9876 { 9858 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
9877 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, 9859 affects_type_identity, handler, exclude } */
9878 affects_type_identity } */ 9860 { "progmem", 0, 0, false, false, false, false,
9879 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute, 9861 avr_handle_progmem_attribute, NULL },
9880 false }, 9862 { "signal", 0, 0, true, false, false, false,
9881 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute, 9863 avr_handle_fndecl_attribute, NULL },
9882 false }, 9864 { "interrupt", 0, 0, true, false, false, false,
9883 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute, 9865 avr_handle_fndecl_attribute, NULL },
9884 false }, 9866 { "no_gccisr", 0, 0, true, false, false, false,
9885 { "no_gccisr", 0, 0, true, false, false, avr_handle_fndecl_attribute, 9867 avr_handle_fndecl_attribute, NULL },
9886 false }, 9868 { "naked", 0, 0, false, true, true, false,
9887 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute, 9869 avr_handle_fntype_attribute, NULL },
9888 false }, 9870 { "OS_task", 0, 0, false, true, true, false,
9889 { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute, 9871 avr_handle_fntype_attribute, NULL },
9890 false }, 9872 { "OS_main", 0, 0, false, true, true, false,
9891 { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute, 9873 avr_handle_fntype_attribute, NULL },
9892 false }, 9874 { "io", 0, 1, true, false, false, false,
9893 { "io", 0, 1, true, false, false, avr_handle_addr_attribute, 9875 avr_handle_addr_attribute, NULL },
9894 false }, 9876 { "io_low", 0, 1, true, false, false, false,
9895 { "io_low", 0, 1, true, false, false, avr_handle_addr_attribute, 9877 avr_handle_addr_attribute, NULL },
9896 false }, 9878 { "address", 1, 1, true, false, false, false,
9897 { "address", 1, 1, true, false, false, avr_handle_addr_attribute, 9879 avr_handle_addr_attribute, NULL },
9898 false }, 9880 { "absdata", 0, 0, true, false, false, false,
9899 { "absdata", 0, 0, true, false, false, avr_handle_absdata_attribute, 9881 avr_handle_absdata_attribute, NULL },
9900 false }, 9882 { NULL, 0, 0, false, false, false, false, NULL, NULL }
9901 { NULL, 0, 0, false, false, false, NULL, false }
9902 }; 9883 };
9903 9884
9904 9885
9905 /* Return true if we support address space AS for the architecture in effect 9886 /* Return true if we support address space AS for the architecture in effect
9906 and false, otherwise. If LOC is not UNKNOWN_LOCATION then also issue 9887 and false, otherwise. If LOC is not UNKNOWN_LOCATION then also issue
10100 10081
10101 return reason == NULL; 10082 return reason == NULL;
10102 } 10083 }
10103 10084
10104 10085
10105 /* Add the section attribute if the variable is in progmem. */ 10086 /* Implement `TARGET_INSERT_ATTRIBUTES'. */
10106 10087
10107 static void 10088 static void
10108 avr_insert_attributes (tree node, tree *attributes) 10089 avr_insert_attributes (tree node, tree *attributes)
10109 { 10090 {
10110 avr_pgm_check_var_decl (node); 10091 avr_pgm_check_var_decl (node);
10092
10093 if (TARGET_MAIN_IS_OS_TASK
10094 && TREE_CODE (node) == FUNCTION_DECL
10095 && MAIN_NAME_P (DECL_NAME (node))
10096 // FIXME: We'd like to also test `flag_hosted' which is only
10097 // available in the C-ish fronts, hence no such test for now.
10098 // Instead, we test the return type of "main" which is not exactly
10099 // the same but good enough.
10100 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (node)))
10101 && NULL == lookup_attribute ("OS_task", *attributes))
10102 {
10103 *attributes = tree_cons (get_identifier ("OS_task"),
10104 NULL, *attributes);
10105 }
10106
10107 /* Add the section attribute if the variable is in progmem. */
10111 10108
10112 if (TREE_CODE (node) == VAR_DECL 10109 if (TREE_CODE (node) == VAR_DECL
10113 && (TREE_STATIC (node) || DECL_EXTERNAL (node)) 10110 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
10114 && avr_progmem_p (node, *attributes)) 10111 && avr_progmem_p (node, *attributes))
10115 { 10112 {
10262 /* Override section callbacks to keep track of `avr_need_clear_bss_p' 10259 /* Override section callbacks to keep track of `avr_need_clear_bss_p'
10263 resp. `avr_need_copy_data_p'. If flash is not mapped to RAM then 10260 resp. `avr_need_copy_data_p'. If flash is not mapped to RAM then
10264 we have also to track .rodata because it is located in RAM then. */ 10261 we have also to track .rodata because it is located in RAM then. */
10265 10262
10266 #if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH 10263 #if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH
10267 if (0 == avr_arch->flash_pm_offset) 10264 if (avr_arch->flash_pm_offset == 0)
10268 #endif 10265 #endif
10269 readonly_data_section->unnamed.callback = avr_output_data_section_asm_op; 10266 readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
10270 data_section->unnamed.callback = avr_output_data_section_asm_op; 10267 data_section->unnamed.callback = avr_output_data_section_asm_op;
10271 bss_section->unnamed.callback = avr_output_bss_section_asm_op; 10268 bss_section->unnamed.callback = avr_output_bss_section_asm_op;
10272 } 10269 }
10300 avr_need_copy_data_p = (STR_PREFIX_P (name, ".data") 10297 avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
10301 || STR_PREFIX_P (name, ".gnu.linkonce.d")); 10298 || STR_PREFIX_P (name, ".gnu.linkonce.d"));
10302 10299
10303 if (!avr_need_copy_data_p 10300 if (!avr_need_copy_data_p
10304 #if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH 10301 #if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH
10305 && 0 == avr_arch->flash_pm_offset 10302 && avr_arch->flash_pm_offset == 0
10306 #endif 10303 #endif
10307 ) 10304 )
10308 avr_need_copy_data_p = (STR_PREFIX_P (name, ".rodata") 10305 avr_need_copy_data_p = (STR_PREFIX_P (name, ".rodata")
10309 || STR_PREFIX_P (name, ".gnu.linkonce.r")); 10306 || STR_PREFIX_P (name, ".gnu.linkonce.r"));
10310 10307
10436 addr_space_t as = TYPE_ADDR_SPACE (type); 10433 addr_space_t as = TYPE_ADDR_SPACE (type);
10437 10434
10438 /* PSTR strings are in generic space but located in flash: 10435 /* PSTR strings are in generic space but located in flash:
10439 patch address space. */ 10436 patch address space. */
10440 10437
10441 if (!AVR_TINY 10438 if (!AVR_TINY && avr_progmem_p (decl, attr) == -1)
10442 && -1 == avr_progmem_p (decl, attr))
10443 as = ADDR_SPACE_FLASH; 10439 as = ADDR_SPACE_FLASH;
10444 10440
10445 AVR_SYMBOL_SET_ADDR_SPACE (sym, as); 10441 AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
10446 10442
10447 tree io_low_attr = lookup_attribute ("io_low", attr); 10443 tree io_low_attr = lookup_attribute ("io_low", attr);
10476 && VAR_DECL == TREE_CODE (decl) 10472 && VAR_DECL == TREE_CODE (decl)
10477 && MEM_P (rtl) 10473 && MEM_P (rtl)
10478 && SYMBOL_REF_P (XEXP (rtl, 0))) 10474 && SYMBOL_REF_P (XEXP (rtl, 0)))
10479 { 10475 {
10480 rtx sym = XEXP (rtl, 0); 10476 rtx sym = XEXP (rtl, 0);
10481 bool progmem_p = -1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl)); 10477 bool progmem_p = avr_progmem_p (decl, DECL_ATTRIBUTES (decl)) == -1;
10482 10478
10483 if (progmem_p) 10479 if (progmem_p)
10484 { 10480 {
10485 // Tag symbols for addition of 0x4000 (avr_arch->flash_pm_offset). 10481 // Tag symbols for addition of 0x4000 (avr_arch->flash_pm_offset).
10486 SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM; 10482 SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM;
12088 and thus is suitable to be skipped by CPSE, SBRC, etc. */ 12084 and thus is suitable to be skipped by CPSE, SBRC, etc. */
12089 12085
12090 static bool 12086 static bool
12091 avr_2word_insn_p (rtx_insn *insn) 12087 avr_2word_insn_p (rtx_insn *insn)
12092 { 12088 {
12093 if (TARGET_SKIP_BUG 12089 if (TARGET_SKIP_BUG || !insn || get_attr_length (insn) != 2)
12094 || !insn
12095 || 2 != get_attr_length (insn))
12096 { 12090 {
12097 return false; 12091 return false;
12098 } 12092 }
12099 12093
12100 switch (INSN_CODE (insn)) 12094 switch (INSN_CODE (insn))
12399 rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0); 12393 rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
12400 rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2); 12394 rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
12401 12395
12402 if (INTVAL (lo16) == INTVAL (hi16)) 12396 if (INTVAL (lo16) == INTVAL (hi16))
12403 { 12397 {
12404 if (0 != INTVAL (lo16) 12398 if (INTVAL (lo16) != 0 || !clear_p)
12405 || !clear_p) 12399 avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
12406 {
12407 avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
12408 }
12409 12400
12410 break; 12401 break;
12411 } 12402 }
12412 } 12403 }
12413 12404
12455 if (done_byte) 12446 if (done_byte)
12456 continue; 12447 continue;
12457 12448
12458 /* Need no clobber reg for -1: Use CLR/DEC */ 12449 /* Need no clobber reg for -1: Use CLR/DEC */
12459 12450
12460 if (-1 == ival[n]) 12451 if (ival[n] == -1)
12461 { 12452 {
12462 if (!clear_p) 12453 if (!clear_p)
12463 avr_asm_len ("clr %0", &xdest[n], len, 1); 12454 avr_asm_len ("clr %0", &xdest[n], len, 1);
12464 12455
12465 avr_asm_len ("dec %0", &xdest[n], len, 1); 12456 avr_asm_len ("dec %0", &xdest[n], len, 1);
12466 continue; 12457 continue;
12467 } 12458 }
12468 else if (1 == ival[n]) 12459 else if (ival[n] == 1)
12469 { 12460 {
12470 if (!clear_p) 12461 if (!clear_p)
12471 avr_asm_len ("clr %0", &xdest[n], len, 1); 12462 avr_asm_len ("clr %0", &xdest[n], len, 1);
12472 12463
12473 avr_asm_len ("inc %0", &xdest[n], len, 1); 12464 avr_asm_len ("inc %0", &xdest[n], len, 1);
13687 13678
13688 bool 13679 bool
13689 avr_has_nibble_0xf (rtx ival) 13680 avr_has_nibble_0xf (rtx ival)
13690 { 13681 {
13691 unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode); 13682 unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode);
13692 return 0 != avr_map_metric (map, MAP_MASK_PREIMAGE_F); 13683 return avr_map_metric (map, MAP_MASK_PREIMAGE_F) != 0;
13693 } 13684 }
13694 13685
13695 13686
13696 /* We have a set of bits that are mapped by a function F. 13687 /* We have a set of bits that are mapped by a function F.
13697 Try to decompose F by means of a second function G so that 13688 Try to decompose F by means of a second function G so that
13754 If result.cost < 0 then such a decomposition does not exist. */ 13745 If result.cost < 0 then such a decomposition does not exist. */
13755 13746
13756 static avr_map_op_t 13747 static avr_map_op_t
13757 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p) 13748 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p)
13758 { 13749 {
13759 bool val_used_p = 0 != avr_map_metric (f, MAP_MASK_PREIMAGE_F); 13750 bool val_used_p = avr_map_metric (f, MAP_MASK_PREIMAGE_F) != 0;
13760 avr_map_op_t f_ginv = *g; 13751 avr_map_op_t f_ginv = *g;
13761 unsigned int ginv = g->ginv; 13752 unsigned int ginv = g->ginv;
13762 13753
13763 f_ginv.cost = -1; 13754 f_ginv.cost = -1;
13764 13755
13785 The overall cost of doing an operation prior to the insertion is 13776 The overall cost of doing an operation prior to the insertion is
13786 the cost of the insertion plus the cost of the operation. */ 13777 the cost of the insertion plus the cost of the operation. */
13787 13778
13788 /* Step 2a: Compute cost of F o G^-1 */ 13779 /* Step 2a: Compute cost of F o G^-1 */
13789 13780
13790 if (0 == avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7)) 13781 if (avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7) == 0)
13791 { 13782 /* The mapping consists only of fixed points and can be folded
13792 /* The mapping consists only of fixed points and can be folded 13783 to AND/OR logic in the remainder. Reasonable cost is 3. */
13793 to AND/OR logic in the remainder. Reasonable cost is 3. */ 13784 f_ginv.cost = 2 + (val_used_p && !val_const_p);
13794
13795 f_ginv.cost = 2 + (val_used_p && !val_const_p);
13796 }
13797 else 13785 else
13798 { 13786 {
13799 rtx xop[4]; 13787 rtx xop[4];
13800 13788
13801 /* Get the cost of the insn by calling the output worker with some 13789 /* Get the cost of the insn by calling the output worker with some
14497 14485
14498 tmap = wide_int_to_tree (map_type, wi::to_wide (arg[0])); 14486 tmap = wide_int_to_tree (map_type, wi::to_wide (arg[0]));
14499 map = TREE_INT_CST_LOW (tmap); 14487 map = TREE_INT_CST_LOW (tmap);
14500 14488
14501 if (TREE_CODE (tval) != INTEGER_CST 14489 if (TREE_CODE (tval) != INTEGER_CST
14502 && 0 == avr_map_metric (map, MAP_MASK_PREIMAGE_F)) 14490 && avr_map_metric (map, MAP_MASK_PREIMAGE_F) == 0)
14503 { 14491 {
14504 /* There are no F in the map, i.e. 3rd operand is unused. 14492 /* There are no F in the map, i.e. 3rd operand is unused.
14505 Replace that argument with some constant to render 14493 Replace that argument with some constant to render
14506 respective input unused. */ 14494 respective input unused. */
14507 14495
14508 tval = build_int_cst (val_type, 0); 14496 tval = build_int_cst (val_type, 0);
14509 changed = true; 14497 changed = true;
14510 } 14498 }
14511 14499
14512 if (TREE_CODE (tbits) != INTEGER_CST 14500 if (TREE_CODE (tbits) != INTEGER_CST
14513 && 0 == avr_map_metric (map, MAP_PREIMAGE_0_7)) 14501 && avr_map_metric (map, MAP_PREIMAGE_0_7) == 0)
14514 { 14502 {
14515 /* Similar for the bits to be inserted. If they are unused, 14503 /* Similar for the bits to be inserted. If they are unused,
14516 we can just as well pass 0. */ 14504 we can just as well pass 0. */
14517 14505
14518 tbits = build_int_cst (val_type, 0); 14506 tbits = build_int_cst (val_type, 0);
14547 return build_call_expr (fndecl, 3, tmap, tbits, tval); 14535 return build_call_expr (fndecl, 3, tmap, tbits, tval);
14548 14536
14549 /* If bits don't change their position we can use vanilla logic 14537 /* If bits don't change their position we can use vanilla logic
14550 to merge the two arguments. */ 14538 to merge the two arguments. */
14551 14539
14552 if (0 == avr_map_metric (map, MAP_NONFIXED_0_7)) 14540 if (avr_map_metric (map, MAP_NONFIXED_0_7) == 0)
14553 { 14541 {
14554 int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F); 14542 int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
14555 tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff); 14543 tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
14556 14544
14557 tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval); 14545 tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);