]>
Commit | Line | Data |
---|---|---|
64c2fd3a JR |
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"); | |
6 | } | |
7 | ||
8 | +/* Return nonzero if FUNC is an nmi function as specified | |
9 | + by the "nmi" attribute. */ | |
10 | + | |
11 | +static int | |
12 | +avr_nmi_function_p (tree func) | |
13 | +{ | |
14 | + return avr_lookup_function_attribute1 (func, "nmi"); | |
15 | +} | |
16 | + | |
17 | /* Return nonzero if FUNC is a signal function as specified | |
18 | by the "signal" attribute. */ | |
19 | ||
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); | |
27 | ||
28 | - isr = cfun->machine->is_interrupt ? "interrupt" : "signal"; | |
29 | + if (cfun->machine->is_interrupt) | |
30 | + isr = "interrupt"; | |
31 | + else if (cfun->machine->is_nmi) | |
32 | + isr = "nmi"; | |
33 | + else | |
34 | + isr = "signal"; | |
35 | ||
36 | /* Too much attributes make no sense as they request conflicting features. */ | |
37 | ||
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); | |
44 | ||
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"); | |
48 | ||
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) | |
52 | { | |
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[] = | |
56 | false }, | |
57 | { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute, | |
58 | false }, | |
59 | + { "nmi", 0, 0, true, false, false, avr_handle_fndecl_attribute, | |
60 | + false }, | |
61 | { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute, | |
62 | false }, | |
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. */ | |
70 | int is_signal; | |
71 | + | |
72 | + /* 'true' - if current function is an nmi function | |
73 | + as specified by the "nmi" attribute. */ | |
74 | + int is_nmi; | |
75 | ||
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 | |
81 | @@ -0,0 +1,13 @@ | |
82 | +/* Test warning emitted for functions with nmi attribute that do | |
83 | + * not start with __vector */ | |
84 | +/* { dg-do compile } */ | |
85 | + | |
86 | + | |
87 | +void __attribute__((interrupt)) interrupt_fun() /* { dg-warning "'interrupt_fun' appears to be a misspelled interrupt handler" } */ | |
88 | +{} | |
89 | + | |
90 | +void __attribute__((signal)) signal_fun() /* { dg-warning "'signal_fun' appears to be a misspelled signal handler" } */ | |
91 | +{} | |
92 | + | |
93 | +void __attribute__((nmi)) nmi_fun() /* { dg-warning "'nmi_fun' appears to be a misspelled nmi handler" } */ | |
94 | +{} | |
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 | |
98 | @@ -0,0 +1,15 @@ | |
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" } } */ | |
104 | + | |
105 | +void func() | |
106 | +{ | |
107 | + volatile int val = *((int *)0x20); | |
108 | + *((int *)0x20) = 0xCAFE; | |
109 | + | |
110 | +} | |
111 | + | |
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 | |
117 | @@ -0,0 +1,14 @@ | |
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" } } */ | |
123 | + | |
124 | +void func() | |
125 | +{ | |
126 | + volatile char val = *((char *)0x20); | |
127 | + *((char *)0x20) = 42; | |
128 | +} | |
129 | + | |
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 | |
135 | @@ -0,0 +1,14 @@ | |
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" } } */ | |
141 | + | |
142 | +void __attribute__((interrupt)) __vector_1() | |
143 | +{ | |
144 | + volatile int w = 19, x = 20, y = 30, z = 42; | |
145 | +} | |
146 | + | |
147 | +/* { dg-final { scan-assembler-not "\tcli" } } */ | |
148 | +/* { dg-final { scan-assembler "\tout __SP_L__,r\\d+\n\tout __SP_H__,r\\d+" } } */ | |
149 | + | |
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 | |
153 | @@ -0,0 +1,18 @@ | |
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 | |
156 | + function */ | |
157 | +/* { dg-do compile } */ | |
158 | +/* { dg-options "-Os" } */ | |
159 | +/* { dg-skip-if "Only for XMEGAs" { "avr-*-*" } { "*" } { "-mmcu=atxmega128a1" } } */ | |
160 | + | |
161 | +void __attribute__((interrupt)) __vector_1() | |
162 | +{ | |
163 | +} | |
164 | + | |
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" } } */ | |
171 | + |