1 diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
2 --- gcc/config/avr/avr.c 2012-09-04 15:08:42.000000000 +0530
3 +++ gcc/config/avr/avr.c 2012-11-09 19:01:17.000000000 +0530
4 @@ -490,6 +490,15 @@ avr_interrupt_function_p (tree func)
5 return avr_lookup_function_attribute1 (func, "interrupt");
8 +/* Return nonzero if FUNC is an nmi function as specified
9 + by the "nmi" attribute. */
12 +avr_nmi_function_p (tree func)
14 + return avr_lookup_function_attribute1 (func, "nmi");
17 /* Return nonzero if FUNC is a signal function as specified
18 by the "signal" attribute. */
20 @@ -536,15 +545,22 @@ avr_set_current_function (tree decl)
21 cfun->machine->is_naked = avr_naked_function_p (decl);
22 cfun->machine->is_signal = avr_signal_function_p (decl);
23 cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
24 + cfun->machine->is_nmi = avr_nmi_function_p (decl);
25 cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
26 cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
28 - isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
29 + if (cfun->machine->is_interrupt)
31 + else if (cfun->machine->is_nmi)
36 /* Too much attributes make no sense as they request conflicting features. */
38 if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
39 - + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
40 + + (cfun->machine->is_signal || cfun->machine->is_interrupt
41 + || cfun->machine->is_nmi) > 1)
42 error_at (loc, "function attributes %qs, %qs and %qs are mutually"
43 " exclusive", "OS_task", "OS_main", isr);
45 @@ -555,7 +571,8 @@ avr_set_current_function (tree decl)
46 warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
47 " no effect on %qs function", "OS_task", "OS_main", "naked");
49 - if (cfun->machine->is_interrupt || cfun->machine->is_signal)
50 + if (cfun->machine->is_interrupt || cfun->machine->is_signal
51 + || cfun->machine->is_nmi)
53 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
54 tree ret = TREE_TYPE (TREE_TYPE (decl));
55 @@ -6827,6 +6844,8 @@ avr_attribute_table[] =
57 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute,
59 + { "nmi", 0, 0, true, false, false, avr_handle_fndecl_attribute,
61 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute,
63 { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute,
64 diff -Naurp gcc/config/avr/avr.h gcc/config/avr/avr.h
65 --- gcc/config/avr/avr.h 2012-06-28 19:28:32.000000000 +0530
66 +++ gcc/config/avr/avr.h 2012-11-09 19:01:17.000000000 +0530
67 @@ -683,6 +683,10 @@ struct GTY(()) machine_function
68 /* 'true' - if current function is a signal function
69 as specified by the "signal" attribute. */
72 + /* 'true' - if current function is an nmi function
73 + as specified by the "nmi" attribute. */
76 /* 'true' - if current function is a 'task' function
77 as specified by the "OS_task" attribute. */
78 diff -Naurp gcc/testsuite/gcc.target/avr/misspelled-handler-warning.c gcc/testsuite/gcc.target/avr/misspelled-handler-warning.c
79 --- gcc/testsuite/gcc.target/avr/misspelled-handler-warning.c 1970-01-01 05:30:00.000000000 +0530
80 +++ gcc/testsuite/gcc.target/avr/misspelled-handler-warning.c 2012-11-09 19:01:17.000000000 +0530
82 +/* Test warning emitted for functions with nmi attribute that do
83 + * not start with __vector */
84 +/* { dg-do compile } */
87 +void __attribute__((interrupt)) interrupt_fun() /* { dg-warning "'interrupt_fun' appears to be a misspelled interrupt handler" } */
90 +void __attribute__((signal)) signal_fun() /* { dg-warning "'signal_fun' appears to be a misspelled signal handler" } */
93 +void __attribute__((nmi)) nmi_fun() /* { dg-warning "'nmi_fun' appears to be a misspelled nmi handler" } */
95 diff -Naurp gcc/testsuite/gcc.target/avr/xmega_const_hi_io_address.c gcc/testsuite/gcc.target/avr/xmega_const_hi_io_address.c
96 --- gcc/testsuite/gcc.target/avr/xmega_const_hi_io_address.c 1970-01-01 05:30:00.000000000 +0530
97 +++ gcc/testsuite/gcc.target/avr/xmega_const_hi_io_address.c 2012-11-09 19:01:17.000000000 +0530
99 +/* Verify that loading the contents of a constant int address in I/O range
100 + uses two IN instructions with the correct SFR offset for XMEGA*/
101 +/* { dg-do compile } */
102 +/* { dg-options "-Os" } */
103 +/* { dg-skip-if "Only for XMEGAs" { "avr-*-*" } { "*" } { "-mmcu=atxmega128a1" } } */
107 + volatile int val = *((int *)0x20);
108 + *((int *)0x20) = 0xCAFE;
112 +/* { dg-final { scan-assembler "\tin r\\d+,0x20\n\tin r\\d+,0x20\\+1" } } */
113 +/* { dg-final { scan-assembler "\tout 0x20,r\\d+\n\tout 0x20\\+1,r\\d+" } } */
114 diff -Naurp gcc/testsuite/gcc.target/avr/xmega_const_qi_io_address.c gcc/testsuite/gcc.target/avr/xmega_const_qi_io_address.c
115 --- gcc/testsuite/gcc.target/avr/xmega_const_qi_io_address.c 1970-01-01 05:30:00.000000000 +0530
116 +++ gcc/testsuite/gcc.target/avr/xmega_const_qi_io_address.c 2012-11-09 19:01:17.000000000 +0530
118 +/* Verify that loading the contents of a constant address in I/O range
119 + uses the IN instruction with the correct SFR offset for XMEGA*/
120 +/* { dg-do compile } */
121 +/* { dg-options "-Os" } */
122 +/* { dg-skip-if "Only for XMEGAs" { "avr-*-*" } { "*" } { "-mmcu=atxmega128a1" } } */
126 + volatile char val = *((char *)0x20);
127 + *((char *)0x20) = 42;
130 +/* { dg-final { scan-assembler "\tin r\\d+,0x20" } } */
131 +/* { dg-final { scan-assembler "\tout 0x20,r\\d+" } } */
132 diff -Naurp gcc/testsuite/gcc.target/avr/xmega_interrupt_no_cli.c gcc/testsuite/gcc.target/avr/xmega_interrupt_no_cli.c
133 --- gcc/testsuite/gcc.target/avr/xmega_interrupt_no_cli.c 1970-01-01 05:30:00.000000000 +0530
134 +++ gcc/testsuite/gcc.target/avr/xmega_interrupt_no_cli.c 2012-11-09 19:01:17.000000000 +0530
136 +/* Verify that XMEGA interrupts don't have a cli or sei
137 + and that SPL is written before SPH*/
138 +/* { dg-do compile } */
139 +/* { dg-options "-Os" } */
140 +/* { dg-skip-if "Only for XMEGAs" { "avr-*-*" } { "*" } { "-mmcu=atxmega128a1" } } */
142 +void __attribute__((interrupt)) __vector_1()
144 + volatile int w = 19, x = 20, y = 30, z = 42;
147 +/* { dg-final { scan-assembler-not "\tcli" } } */
148 +/* { dg-final { scan-assembler "\tout __SP_L__,r\\d+\n\tout __SP_H__,r\\d+" } } */
150 diff -Naurp gcc/testsuite/gcc.target/avr/xmega_sfr_offsets.c gcc/testsuite/gcc.target/avr/xmega_sfr_offsets.c
151 --- gcc/testsuite/gcc.target/avr/xmega_sfr_offsets.c 1970-01-01 05:30:00.000000000 +0530
152 +++ gcc/testsuite/gcc.target/avr/xmega_sfr_offsets.c 2012-11-09 19:01:17.000000000 +0530
154 +/* Verify that SFR offsets for XMEGAs do not have the 0x20 offset
155 + and that they are saved on entry, restored on exit for an interrupt
157 +/* { dg-do compile } */
158 +/* { dg-options "-Os" } */
159 +/* { dg-skip-if "Only for XMEGAs" { "avr-*-*" } { "*" } { "-mmcu=atxmega128a1" } } */
161 +void __attribute__((interrupt)) __vector_1()
165 +/* { dg-final { scan-assembler "__SREG__ = 0x3f" } } */
166 +/* { dg-final { scan-assembler "__RAMPD__ = 0x38" } } */
167 +/* { dg-final { scan-assembler "\tin r0,__SREG__" } } */
168 +/* { dg-final { scan-assembler "\tin r0,__RAMPD__" } } */
169 +/* { dg-final { scan-assembler "\tpop r0\n\tout __SREG__,r0" } } */
170 +/* { dg-final { scan-assembler "\tpop r0\n\tout __RAMPD__,r0" } } */