]>
Commit | Line | Data |
---|---|---|
40dfa9e4 | 1 | --- ./gcc/config/avr/avr.c.orig 2010-03-08 12:55:13.000000000 +0100 |
2 | +++ ./gcc/config/avr/avr.c 2010-03-08 12:55:36.000000000 +0100 | |
3 | @@ -55,6 +55,7 @@ | |
2bc38036 | 4 | static int avr_naked_function_p (tree); |
5 | static int interrupt_function_p (tree); | |
6 | static int signal_function_p (tree); | |
7 | +static int nmi_function_p (tree); | |
8 | static int avr_OS_task_function_p (tree); | |
9 | static int avr_regs_to_save (HARD_REG_SET *); | |
10 | static int sequent_regs_live (void); | |
40dfa9e4 | 11 | @@ -131,17 +132,24 @@ |
2bc38036 | 12 | int avr_have_movw_lpmx_p = 0; |
13 | ||
14 | static const struct base_arch_s avr_arch_types[] = { | |
15 | - { 1, 0, 0, 0, 0, 0, 0, 0, NULL }, /* unknown device specified */ | |
16 | - { 1, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=1" }, | |
17 | - { 0, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=2" }, | |
18 | - { 0, 0, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=25" }, | |
19 | - { 0, 0, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=3" }, | |
20 | - { 0, 0, 1, 0, 1, 0, 0, 0, "__AVR_ARCH__=31" }, | |
21 | - { 0, 0, 1, 1, 0, 0, 0, 0, "__AVR_ARCH__=35" }, | |
22 | - { 0, 1, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=4" }, | |
23 | - { 0, 1, 1, 1, 0, 0, 0, 0, "__AVR_ARCH__=5" }, | |
24 | - { 0, 1, 1, 1, 1, 1, 0, 0, "__AVR_ARCH__=51" }, | |
25 | - { 0, 1, 1, 1, 1, 1, 1, 0, "__AVR_ARCH__=6" } | |
26 | + { 1, 0, 0, 0, 0, 0, 0, 0, 0, NULL }, /* Unknown device specified. */ | |
27 | + { 1, 0, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=1" }, | |
28 | + { 0, 0, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=2" }, | |
29 | + { 0, 0, 0, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=25" }, | |
30 | + { 0, 0, 1, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=3" }, | |
31 | + { 0, 0, 1, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=31" }, | |
32 | + { 0, 0, 1, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=35" }, | |
33 | + { 0, 1, 0, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=4" }, | |
34 | + { 0, 1, 1, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=5" }, | |
35 | + { 0, 1, 1, 1, 1, 1, 0, 0, 0, "__AVR_ARCH__=51" }, | |
36 | + { 0, 1, 1, 1, 1, 1, 1, 0, 0, "__AVR_ARCH__=6" }, | |
37 | + { 0, 1, 0, 1, 0, 0, 0, 1, 0, "__AVR_ARCH__=101" }, | |
38 | + { 0, 1, 1, 1, 0, 0, 0, 1, 0, "__AVR_ARCH__=102" }, | |
39 | + { 0, 1, 1, 1, 0, 0, 0, 1, 1, "__AVR_ARCH__=103" }, | |
40 | + { 0, 1, 1, 1, 1, 1, 0, 1, 0, "__AVR_ARCH__=104" }, | |
41 | + { 0, 1, 1, 1, 1, 1, 0, 1, 1, "__AVR_ARCH__=105" }, | |
42 | + { 0, 1, 1, 1, 1, 1, 1, 1, 0, "__AVR_ARCH__=106" }, | |
43 | + { 0, 1, 1, 1, 1, 1, 1, 1, 1, "__AVR_ARCH__=107" } | |
44 | }; | |
45 | ||
46 | /* These names are used as the index into the avr_arch_types[] table | |
40dfa9e4 | 47 | @@ -159,7 +167,14 @@ |
2bc38036 | 48 | ARCH_AVR4, |
49 | ARCH_AVR5, | |
50 | ARCH_AVR51, | |
51 | - ARCH_AVR6 | |
52 | + ARCH_AVR6, | |
53 | + ARCH_AVRXMEGA1, | |
54 | + ARCH_AVRXMEGA2, | |
55 | + ARCH_AVRXMEGA3, | |
56 | + ARCH_AVRXMEGA4, | |
57 | + ARCH_AVRXMEGA5, | |
58 | + ARCH_AVRXMEGA6, | |
59 | + ARCH_AVRXMEGA7 | |
60 | }; | |
61 | ||
62 | struct mcu_type_s { | |
40dfa9e4 | 63 | @@ -349,6 +364,35 @@ |
2bc38036 | 64 | { "avr6", ARCH_AVR6, NULL }, |
65 | { "atmega2560", ARCH_AVR6, "__AVR_ATmega2560__" }, | |
66 | { "atmega2561", ARCH_AVR6, "__AVR_ATmega2561__" }, | |
67 | + /* Enhanced, == 256K. */ | |
68 | + /* Xmega, <= 8K FLASH. */ | |
69 | + /* Xmega, > 8K, <= 64K FLASH, <= 64K RAM. */ | |
40dfa9e4 | 70 | + { "avrxmega2", ARCH_AVRXMEGA2, NULL }, |
71 | + { "atxmega16a4", ARCH_AVRXMEGA2, "__AVR_ATxmega16A4__" }, | |
72 | + { "atxmega16d4", ARCH_AVRXMEGA2, "__AVR_ATxmega16D4__" }, | |
73 | + { "atxmega32d4", ARCH_AVRXMEGA2, "__AVR_ATxmega32D4__" }, | |
2bc38036 | 74 | + /* Xmega, > 8K, <= 64K FLASH, > 64K RAM. */ |
40dfa9e4 | 75 | + { "avrxmega3", ARCH_AVRXMEGA3, NULL }, |
76 | + { "atxmega32a4", ARCH_AVRXMEGA3, "__AVR_ATxmega32A4__" }, | |
2bc38036 | 77 | + /* Xmega, > 64K, <= 128K FLASH, <= 64K RAM. */ |
40dfa9e4 | 78 | + { "avrxmega4", ARCH_AVRXMEGA4, NULL }, |
79 | + { "atxmega64a3", ARCH_AVRXMEGA4, "__AVR_ATxmega64A3__" }, | |
80 | + { "atxmega64d3", ARCH_AVRXMEGA4, "__AVR_ATxmega64D3__" }, | |
2bc38036 | 81 | + /* Xmega, > 64K, <= 128K FLASH, > 64K RAM. */ |
82 | + { "avrxmega5", ARCH_AVRXMEGA5, NULL }, | |
83 | + { "atxmega64a1", ARCH_AVRXMEGA5, "__AVR_ATxmega64A1__" }, | |
84 | + /* Xmega, > 128K, <= 256K FLASH, <= 64K RAM. */ | |
40dfa9e4 | 85 | + { "avrxmega6", ARCH_AVRXMEGA6, NULL }, |
86 | + { "atxmega128a3", ARCH_AVRXMEGA6, "__AVR_ATxmega128A3__" }, | |
87 | + { "atxmega128d3", ARCH_AVRXMEGA6, "__AVR_ATxmega128D3__" }, | |
88 | + { "atxmega192a3", ARCH_AVRXMEGA6, "__AVR_ATxmega192A3__" }, | |
89 | + { "atxmega192d3", ARCH_AVRXMEGA6, "__AVR_ATxmega192D3__" }, | |
90 | + { "atxmega256a3", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3__" }, | |
91 | + { "atxmega256a3b",ARCH_AVRXMEGA6, "__AVR_ATxmega256A3B__" }, | |
92 | + { "atxmega256d3", ARCH_AVRXMEGA6, "__AVR_ATxmega256D3__" }, | |
2bc38036 | 93 | + /* Xmega, > 128K, <= 256K FLASH, > 64K RAM. */ |
94 | + { "avrxmega7", ARCH_AVRXMEGA7, NULL }, | |
95 | + { "atxmega128a1", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1__" }, | |
96 | /* Assembler only. */ | |
97 | { "avr1", ARCH_AVR1, NULL }, | |
98 | { "at90s1200", ARCH_AVR1, "__AVR_AT90S1200__" }, | |
40dfa9e4 | 99 | @@ -531,6 +575,21 @@ |
2bc38036 | 100 | return a != NULL_TREE; |
101 | } | |
102 | ||
103 | +/* Return nonzero if FUNC is a nmi function as specified | |
104 | + by the "nmi" attribute. */ | |
105 | + | |
106 | +static int | |
107 | +nmi_function_p (tree func) | |
108 | +{ | |
109 | + tree a; | |
110 | + | |
111 | + if (TREE_CODE (func) != FUNCTION_DECL) | |
112 | + return 0; | |
113 | + | |
114 | + a = lookup_attribute ("nmi", DECL_ATTRIBUTES (func)); | |
115 | + return a != NULL_TREE; | |
116 | +} | |
117 | + | |
118 | /* Return nonzero if FUNC is a OS_task function. */ | |
119 | ||
120 | static int | |
40dfa9e4 | 121 | @@ -690,6 +749,7 @@ |
2bc38036 | 122 | cfun->machine->is_naked = avr_naked_function_p (current_function_decl); |
123 | cfun->machine->is_interrupt = interrupt_function_p (current_function_decl); | |
124 | cfun->machine->is_signal = signal_function_p (current_function_decl); | |
125 | + cfun->machine->is_nmi = nmi_function_p (current_function_decl); | |
126 | cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl); | |
127 | ||
128 | /* Prologue: naked. */ | |
40dfa9e4 | 129 | @@ -725,17 +785,48 @@ |
2bc38036 | 130 | |
131 | /* Push SREG. */ | |
132 | insn = emit_move_insn (tmp_reg_rtx, | |
133 | - gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR))); | |
134 | + gen_rtx_MEM (QImode, GEN_INT (AVR_SREG_ADDR))); | |
135 | RTX_FRAME_RELATED_P (insn) = 1; | |
136 | insn = emit_move_insn (pushbyte, tmp_reg_rtx); | |
137 | RTX_FRAME_RELATED_P (insn) = 1; | |
40dfa9e4 | 138 | |
139 | + /* Push RAMPD, RAMPX, RAMPY. */ | |
140 | + if (AVR_HAVE_RAMPX_Y_D) | |
141 | + { | |
142 | + /* Push RAMPD. */ | |
143 | + insn = emit_move_insn (tmp_reg_rtx, | |
144 | + gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPD_ADDR))); | |
145 | + RTX_FRAME_RELATED_P (insn) = 1; | |
146 | + insn = emit_move_insn (pushbyte, tmp_reg_rtx); | |
147 | + RTX_FRAME_RELATED_P (insn) = 1; | |
148 | + | |
149 | + /* Push RAMPX. */ | |
150 | + if (TEST_HARD_REG_BIT (set, REG_X) && TEST_HARD_REG_BIT (set, REG_X + 1)) | |
151 | + { | |
152 | + insn = emit_move_insn (tmp_reg_rtx, | |
153 | + gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPX_ADDR))); | |
154 | + RTX_FRAME_RELATED_P (insn) = 1; | |
155 | + insn = emit_move_insn (pushbyte, tmp_reg_rtx); | |
156 | + RTX_FRAME_RELATED_P (insn) = 1; | |
157 | + } | |
158 | + | |
159 | + /* Push RAMPY. */ | |
160 | + if (TEST_HARD_REG_BIT (set, REG_Y) && TEST_HARD_REG_BIT (set, REG_Y + 1)) | |
161 | + { | |
162 | + insn = emit_move_insn (tmp_reg_rtx, | |
163 | + gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPY_ADDR))); | |
164 | + RTX_FRAME_RELATED_P (insn) = 1; | |
165 | + insn = emit_move_insn (pushbyte, tmp_reg_rtx); | |
166 | + RTX_FRAME_RELATED_P (insn) = 1; | |
167 | + } | |
168 | + } | |
169 | + | |
170 | /* Push RAMPZ. */ | |
171 | if(AVR_HAVE_RAMPZ | |
2bc38036 | 172 | && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1))) |
173 | { | |
174 | insn = emit_move_insn (tmp_reg_rtx, | |
175 | - gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR))); | |
176 | + gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPZ_ADDR))); | |
177 | RTX_FRAME_RELATED_P (insn) = 1; | |
178 | insn = emit_move_insn (pushbyte, tmp_reg_rtx); | |
179 | RTX_FRAME_RELATED_P (insn) = 1; | |
40dfa9e4 | 180 | @@ -744,9 +835,46 @@ |
181 | /* Clear zero reg. */ | |
182 | insn = emit_move_insn (zero_reg_rtx, const0_rtx); | |
183 | RTX_FRAME_RELATED_P (insn) = 1; | |
184 | - | |
185 | + | |
186 | /* Prevent any attempt to delete the setting of ZERO_REG! */ | |
187 | emit_insn (gen_rtx_USE (VOIDmode, zero_reg_rtx)); | |
188 | + | |
189 | + /* | |
190 | + Clear RAMP? registers if used for data access in the interrupt/signal | |
191 | + context. Do this after the zero register has been explictly cleared. | |
192 | + */ | |
193 | + if (AVR_HAVE_RAMPX_Y_D) | |
194 | + { | |
195 | + /* Set RAMPD to 0. */ | |
196 | + insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPD_ADDR)), | |
197 | + const0_rtx); | |
198 | + RTX_FRAME_RELATED_P (insn) = 1; | |
199 | + | |
200 | + if (TEST_HARD_REG_BIT (set, REG_X) && TEST_HARD_REG_BIT (set, REG_X + 1)) | |
201 | + { | |
202 | + /* Set RAMPX to 0. */ | |
203 | + insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPX_ADDR)), | |
204 | + const0_rtx); | |
205 | + RTX_FRAME_RELATED_P (insn) = 1; | |
206 | + } | |
207 | + | |
208 | + if (TEST_HARD_REG_BIT (set, REG_Y) && TEST_HARD_REG_BIT (set, REG_Y + 1)) | |
209 | + { | |
210 | + /* Set RAMPY to 0. */ | |
211 | + insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPY_ADDR)), | |
212 | + const0_rtx); | |
213 | + RTX_FRAME_RELATED_P (insn) = 1; | |
214 | + } | |
215 | + | |
216 | + if(AVR_HAVE_RAMPZ | |
217 | + && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1))) | |
218 | + { | |
219 | + /* Set RAMPZ to 0. */ | |
220 | + insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPZ_ADDR)), | |
221 | + const0_rtx); | |
222 | + RTX_FRAME_RELATED_P (insn) = 1; | |
223 | + } | |
224 | + } | |
225 | } | |
226 | if (minimize && (frame_pointer_needed | |
227 | || (AVR_2_BYTE_PC && live_seq > 6) | |
228 | @@ -1010,14 +1138,39 @@ | |
2bc38036 | 229 | && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1))) |
230 | { | |
231 | emit_insn (gen_popqi (tmp_reg_rtx)); | |
232 | - emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(RAMPZ_ADDR)), | |
233 | + emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(AVR_RAMPZ_ADDR)), | |
234 | tmp_reg_rtx); | |
235 | } | |
236 | ||
40dfa9e4 | 237 | + /* Restore RAMPY, RAMPX, RAMPD using tmp reg as scratch. */ |
238 | + if (AVR_HAVE_RAMPX_Y_D) | |
239 | + { | |
240 | + /* Pop RAMPY. */ | |
241 | + if (TEST_HARD_REG_BIT (set, REG_Y) && TEST_HARD_REG_BIT (set, REG_Y + 1)) | |
242 | + { | |
243 | + emit_insn (gen_popqi (tmp_reg_rtx)); | |
244 | + emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPY_ADDR)), | |
245 | + tmp_reg_rtx); | |
246 | + } | |
247 | + | |
248 | + /* Pop RAMPX. */ | |
249 | + if (TEST_HARD_REG_BIT (set, REG_X) && TEST_HARD_REG_BIT (set, REG_X + 1)) | |
250 | + { | |
251 | + emit_insn (gen_popqi (tmp_reg_rtx)); | |
252 | + emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPX_ADDR)), | |
253 | + tmp_reg_rtx); | |
254 | + } | |
255 | + | |
256 | + /* Pop RAMPD. */ | |
257 | + emit_insn (gen_popqi (tmp_reg_rtx)); | |
258 | + emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPD_ADDR)), | |
259 | + tmp_reg_rtx); | |
260 | + } | |
261 | + | |
2bc38036 | 262 | /* Restore SREG using tmp reg as scratch. */ |
263 | emit_insn (gen_popqi (tmp_reg_rtx)); | |
264 | ||
265 | - emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)), | |
266 | + emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(AVR_SREG_ADDR)), | |
267 | tmp_reg_rtx); | |
268 | ||
269 | /* Restore tmp REG. */ | |
40dfa9e4 | 270 | @@ -1786,8 +1939,9 @@ |
2bc38036 | 271 | } |
272 | /* Use simple load of stack pointer if no interrupts are used | |
273 | or inside main or signal function prologue where they disabled. */ | |
274 | - else if (TARGET_NO_INTERRUPTS | |
275 | - || (reload_completed | |
276 | + else if (TARGET_NO_INTERRUPTS | |
277 | + || (!AVR_XMEGA | |
278 | + && reload_completed | |
279 | && cfun->machine->is_signal | |
280 | && prologue_epilogue_contains (insn))) | |
281 | { | |
40dfa9e4 | 282 | @@ -1796,7 +1950,8 @@ |
2bc38036 | 283 | AS2 (out,__SP_L__,%A1)); |
284 | } | |
285 | /* In interrupt prolog we know interrupts are enabled. */ | |
286 | - else if (reload_completed | |
287 | + else if (!AVR_XMEGA | |
288 | + && reload_completed | |
289 | && cfun->machine->is_interrupt | |
290 | && prologue_epilogue_contains (insn)) | |
291 | { | |
40dfa9e4 | 292 | @@ -1806,12 +1961,21 @@ |
2bc38036 | 293 | "sei" CR_TAB |
294 | AS2 (out,__SP_L__,%A1)); | |
295 | } | |
296 | - *l = 5; | |
297 | - return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB | |
298 | - "cli" CR_TAB | |
299 | - AS2 (out,__SP_H__,%B1) CR_TAB | |
300 | - AS2 (out,__SREG__,__tmp_reg__) CR_TAB | |
301 | - AS2 (out,__SP_L__,%A1)); | |
302 | + if(AVR_XMEGA) | |
303 | + { | |
40dfa9e4 | 304 | + *l = 2; |
305 | + return (AS2 (out,__SP_L__,%A1) CR_TAB | |
306 | + AS2 (out,__SP_H__,%B1)); | |
2bc38036 | 307 | + } |
308 | + else | |
309 | + { | |
310 | + *l = 5; | |
311 | + return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB | |
312 | + "cli" CR_TAB | |
313 | + AS2 (out,__SP_H__,%B1) CR_TAB | |
314 | + AS2 (out,__SREG__,__tmp_reg__) CR_TAB | |
315 | + AS2 (out,__SP_L__,%A1)); | |
316 | + } | |
317 | } | |
318 | else if (test_hard_reg_class (STACK_REG, src)) | |
319 | { | |
40dfa9e4 | 320 | @@ -1946,7 +2110,7 @@ |
2bc38036 | 321 | |
322 | if (CONSTANT_ADDRESS_P (x)) | |
323 | { | |
324 | - if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR) | |
325 | + if (CONST_INT_P (x) && INTVAL (x) == AVR_SREG_ADDR) | |
326 | { | |
327 | *l = 1; | |
328 | return AS2 (in,%0,__SREG__); | |
40dfa9e4 | 329 | @@ -1954,7 +2118,8 @@ |
2bc38036 | 330 | if (avr_io_address_p (x, 1)) |
331 | { | |
332 | *l = 1; | |
333 | - return AS2 (in,%0,%1-0x20); | |
334 | + op[2] = GEN_INT(AVR_IO_OFFSET); | |
335 | + return AS2 (in,%0,%1-%2); | |
336 | } | |
337 | *l = 2; | |
338 | return AS2 (lds,%0,%1); | |
40dfa9e4 | 339 | @@ -2142,8 +2307,9 @@ |
2bc38036 | 340 | if (avr_io_address_p (base, 2)) |
341 | { | |
342 | *l = 2; | |
343 | - return (AS2 (in,%A0,%A1-0x20) CR_TAB | |
344 | - AS2 (in,%B0,%B1-0x20)); | |
345 | + op[2] = GEN_INT(AVR_IO_OFFSET); | |
346 | + return (AS2 (in,%A0,%A1-%2) CR_TAB | |
347 | + AS2 (in,%B0,%B1-%2)); | |
348 | } | |
349 | *l = 4; | |
350 | return (AS2 (lds,%A0,%A1) CR_TAB | |
40dfa9e4 | 351 | @@ -2634,7 +2800,7 @@ |
2bc38036 | 352 | |
353 | if (CONSTANT_ADDRESS_P (x)) | |
354 | { | |
355 | - if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR) | |
356 | + if (CONST_INT_P (x) && INTVAL (x) == AVR_SREG_ADDR) | |
357 | { | |
358 | *l = 1; | |
359 | return AS2 (out,__SREG__,%1); | |
40dfa9e4 | 360 | @@ -2642,7 +2808,8 @@ |
2bc38036 | 361 | if (avr_io_address_p (x, 1)) |
362 | { | |
363 | *l = 1; | |
364 | - return AS2 (out,%0-0x20,%1); | |
365 | + op[2] = GEN_INT(AVR_IO_OFFSET); | |
366 | + return AS2 (out,%0-%2,%1); | |
367 | } | |
368 | *l = 2; | |
369 | return AS2 (sts,%0,%1); | |
40dfa9e4 | 370 | @@ -2721,11 +2888,20 @@ |
2bc38036 | 371 | if (avr_io_address_p (base, 2)) |
372 | { | |
373 | *l = 2; | |
374 | - return (AS2 (out,%B0-0x20,%B1) CR_TAB | |
375 | - AS2 (out,%A0-0x20,%A1)); | |
376 | + op[2] = GEN_INT(AVR_IO_OFFSET); | |
377 | + if (AVR_XMEGA) | |
40dfa9e4 | 378 | + return (AS2 (out,%A0-%2,%A1) CR_TAB |
379 | + AS2 (out,%B0-%2,%B1)); | |
2bc38036 | 380 | + else |
381 | + return (AS2 (out,%B0-%2,%B1) CR_TAB | |
382 | + AS2 (out,%A0-%2,%A1)); | |
383 | } | |
384 | - return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB | |
385 | - AS2 (sts,%A0,%A1)); | |
386 | + if (AVR_XMEGA) | |
387 | + return *l = 4, (AS2 (sts,%A0,%A1) CR_TAB | |
388 | + AS2 (sts,%B0,%B1)); | |
389 | + else | |
390 | + return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB | |
391 | + AS2 (sts,%A0,%A1)); | |
392 | } | |
393 | if (reg_base > 0) | |
394 | { | |
40dfa9e4 | 395 | @@ -2740,11 +2916,20 @@ |
2bc38036 | 396 | AS2 (adiw,r26,1) CR_TAB |
397 | AS2 (st,X,__tmp_reg__)); | |
398 | else | |
399 | - return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB | |
400 | - AS2 (adiw,r26,1) CR_TAB | |
401 | - AS2 (st,X,__tmp_reg__) CR_TAB | |
402 | - AS2 (sbiw,r26,1) CR_TAB | |
403 | - AS2 (st,X,r26)); | |
404 | + { | |
405 | + if (!AVR_XMEGA) | |
406 | + return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB | |
407 | + AS2 (adiw,r26,1) CR_TAB | |
408 | + AS2 (st,X,__tmp_reg__) CR_TAB | |
409 | + AS2 (sbiw,r26,1) CR_TAB | |
410 | + AS2 (st,X,r26)); | |
411 | + else | |
412 | + return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB | |
413 | + AS2 (st,X,r26) CR_TAB | |
414 | + AS2 (adiw,r26,1) CR_TAB | |
415 | + AS2 (st,X,__tmp_reg__) CR_TAB | |
416 | + AS2 (sbiw,r26,1)); | |
417 | + } | |
418 | } | |
419 | else | |
420 | { | |
40dfa9e4 | 421 | @@ -2752,14 +2937,27 @@ |
2bc38036 | 422 | return *l=2, (AS2 (st,X+,%A1) CR_TAB |
423 | AS2 (st,X,%B1)); | |
424 | else | |
425 | - return *l=3, (AS2 (adiw,r26,1) CR_TAB | |
426 | - AS2 (st,X,%B1) CR_TAB | |
427 | - AS2 (st,-X,%A1)); | |
428 | + { | |
429 | + if (!AVR_XMEGA) | |
430 | + return *l=3, (AS2 (adiw,r26,1) CR_TAB | |
431 | + AS2 (st,X,%B1) CR_TAB | |
432 | + AS2 (st,-X,%A1)); | |
433 | + else | |
434 | + return *l=3, (AS2 (st,X+,%A1) CR_TAB | |
435 | + AS2 (st,X,%B1) CR_TAB | |
436 | + AS2 (sbiw,r26,1)); | |
437 | + } | |
438 | } | |
439 | } | |
440 | else | |
441 | - return *l=2, (AS2 (std,%0+1,%B1) CR_TAB | |
442 | - AS2 (st,%0,%A1)); | |
443 | + { | |
444 | + if (!AVR_XMEGA) | |
445 | + return *l=2, (AS2 (std,%0+1,%B1) CR_TAB | |
446 | + AS2 (st,%0,%A1)); | |
447 | + else | |
448 | + return *l=2, (AS2 (st,%0,%A1) CR_TAB | |
449 | + AS2 (std,%0+1,%B1)); | |
450 | + } | |
451 | } | |
452 | else if (GET_CODE (base) == PLUS) | |
453 | { | |
40dfa9e4 | 454 | @@ -2770,48 +2968,104 @@ |
2bc38036 | 455 | if (reg_base != REG_Y) |
456 | fatal_insn ("incorrect insn:",insn); | |
457 | ||
458 | - if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) | |
459 | - return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB | |
460 | - AS2 (std,Y+63,%B1) CR_TAB | |
461 | - AS2 (std,Y+62,%A1) CR_TAB | |
462 | - AS2 (sbiw,r28,%o0-62)); | |
463 | - | |
464 | - return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB | |
465 | - AS2 (sbci,r29,hi8(-%o0)) CR_TAB | |
466 | - AS2 (std,Y+1,%B1) CR_TAB | |
467 | - AS2 (st,Y,%A1) CR_TAB | |
468 | - AS2 (subi,r28,lo8(%o0)) CR_TAB | |
469 | - AS2 (sbci,r29,hi8(%o0))); | |
470 | + if (!AVR_XMEGA) | |
471 | + { | |
472 | + if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) | |
473 | + return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB | |
474 | + AS2 (std,Y+63,%B1) CR_TAB | |
475 | + AS2 (std,Y+62,%A1) CR_TAB | |
476 | + AS2 (sbiw,r28,%o0-62)); | |
477 | + | |
478 | + return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB | |
479 | + AS2 (sbci,r29,hi8(-%o0)) CR_TAB | |
480 | + AS2 (std,Y+1,%B1) CR_TAB | |
481 | + AS2 (st,Y,%A1) CR_TAB | |
482 | + AS2 (subi,r28,lo8(%o0)) CR_TAB | |
483 | + AS2 (sbci,r29,hi8(%o0))); | |
484 | + } | |
485 | + else | |
486 | + { | |
487 | + if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) | |
488 | + return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB | |
489 | + AS2 (std,Y+62,%A1) CR_TAB | |
490 | + AS2 (std,Y+63,%B1) CR_TAB | |
491 | + AS2 (sbiw,r28,%o0-62)); | |
492 | + | |
493 | + return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB | |
494 | + AS2 (sbci,r29,hi8(-%o0)) CR_TAB | |
495 | + AS2 (st,Y,%A1) CR_TAB | |
496 | + AS2 (std,Y+1,%B1) CR_TAB | |
497 | + AS2 (subi,r28,lo8(%o0)) CR_TAB | |
498 | + AS2 (sbci,r29,hi8(%o0))); | |
499 | + } | |
500 | } | |
501 | if (reg_base == REG_X) | |
502 | { | |
503 | /* (X + d) = R */ | |
504 | if (reg_src == REG_X) | |
505 | { | |
506 | - *l = 7; | |
507 | - return (AS2 (mov,__tmp_reg__,r26) CR_TAB | |
508 | - AS2 (mov,__zero_reg__,r27) CR_TAB | |
509 | - AS2 (adiw,r26,%o0+1) CR_TAB | |
510 | - AS2 (st,X,__zero_reg__) CR_TAB | |
511 | - AS2 (st,-X,__tmp_reg__) CR_TAB | |
512 | - AS1 (clr,__zero_reg__) CR_TAB | |
513 | + if (!AVR_XMEGA) | |
514 | + { | |
515 | + *l = 7; | |
516 | + return (AS2 (mov,__tmp_reg__,r26) CR_TAB | |
517 | + AS2 (mov,__zero_reg__,r27) CR_TAB | |
518 | + AS2 (adiw,r26,%o0+1) CR_TAB | |
519 | + AS2 (st,X,__zero_reg__) CR_TAB | |
520 | + AS2 (st,-X,__tmp_reg__) CR_TAB | |
521 | + AS1 (clr,__zero_reg__) CR_TAB | |
522 | + AS2 (sbiw,r26,%o0)); | |
523 | + } | |
524 | + else | |
525 | + { | |
526 | + *l = 7; | |
527 | + return (AS2 (mov,__tmp_reg__,r26) CR_TAB | |
528 | + AS2 (mov,__zero_reg__,r27) CR_TAB | |
529 | + AS2 (adiw,r26,%o0) CR_TAB | |
530 | + AS2 (st,X+,__tmp_reg__) CR_TAB | |
531 | + AS2 (st,X,__zero_reg__) CR_TAB | |
532 | + AS1 (clr,__zero_reg__) CR_TAB | |
533 | + AS2 (sbiw,r26,%o0+1)); | |
534 | + } | |
535 | + } | |
536 | + if (!AVR_XMEGA) | |
537 | + { | |
538 | + *l = 4; | |
539 | + return (AS2 (adiw,r26,%o0+1) CR_TAB | |
540 | + AS2 (st,X,%B1) CR_TAB | |
541 | + AS2 (st,-X,%A1) CR_TAB | |
542 | AS2 (sbiw,r26,%o0)); | |
543 | } | |
544 | - *l = 4; | |
545 | - return (AS2 (adiw,r26,%o0+1) CR_TAB | |
546 | - AS2 (st,X,%B1) CR_TAB | |
547 | - AS2 (st,-X,%A1) CR_TAB | |
548 | - AS2 (sbiw,r26,%o0)); | |
549 | + else | |
550 | + { | |
551 | + *l = 4; | |
552 | + return (AS2 (adiw,r26,%o0) CR_TAB | |
553 | + AS2 (st,X+,%A1) CR_TAB | |
554 | + AS2 (st,X,%B1) CR_TAB | |
555 | + AS2 (sbiw,r26,%o0+1)); | |
556 | + } | |
557 | } | |
558 | - return *l=2, (AS2 (std,%B0,%B1) CR_TAB | |
559 | - AS2 (std,%A0,%A1)); | |
560 | + | |
561 | + if (!AVR_XMEGA) | |
562 | + return *l=2, (AS2 (std,%B0,%B1) CR_TAB | |
563 | + AS2 (std,%A0,%A1)); | |
564 | + else | |
565 | + return *l=2, (AS2 (std,%A0,%A1) CR_TAB | |
566 | + AS2 (std,%B0,%B1)); | |
567 | } | |
568 | else if (GET_CODE (base) == PRE_DEC) /* (--R) */ | |
569 | - return *l=2, (AS2 (st,%0,%B1) CR_TAB | |
570 | - AS2 (st,%0,%A1)); | |
571 | + { | |
572 | + if (mem_volatile_p && AVR_XMEGA) | |
573 | + return *l = 4, (AS2 (sbiw,%r0,1) CR_TAB | |
574 | + AS2 (st,%p0+,%A1) CR_TAB | |
575 | + AS2 (st,%p0,%B1) CR_TAB | |
576 | + AS2 (sbiw,%r0,2)); | |
577 | + else | |
578 | + return *l=2, (AS2 (st,%0,%B1) CR_TAB | |
579 | + AS2 (st,%0,%A1)); | |
580 | + } | |
581 | else if (GET_CODE (base) == POST_INC) /* (R++) */ | |
582 | { | |
583 | - if (mem_volatile_p) | |
584 | + if (mem_volatile_p && !AVR_XMEGA) | |
585 | { | |
586 | if (REGNO (XEXP (base, 0)) == REG_X) | |
587 | { | |
40dfa9e4 | 588 | @@ -2832,7 +3086,7 @@ |
2bc38036 | 589 | |
590 | *l = 2; | |
591 | return (AS2 (st,%0,%A1) CR_TAB | |
592 | - AS2 (st,%0,%B1)); | |
593 | + AS2 (st,%0,%B1)); | |
594 | } | |
595 | fatal_insn ("unknown move insn:",insn); | |
596 | return ""; | |
40dfa9e4 | 597 | @@ -4712,6 +4966,7 @@ |
2bc38036 | 598 | { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute }, |
599 | { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute }, | |
600 | { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute }, | |
601 | + { "nmi", 0, 0, true, false, false, avr_handle_fndecl_attribute }, | |
602 | { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute }, | |
603 | { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute }, | |
604 | { NULL, 0, 0, false, false, false, NULL } | |
40dfa9e4 | 605 | @@ -4800,6 +5055,14 @@ |
2bc38036 | 606 | func_name); |
607 | } | |
608 | } | |
609 | + else if (strncmp (attr, "nmi", strlen ("nmi")) == 0) | |
610 | + { | |
611 | + if (strncmp (func_name, "__vector", strlen ("__vector")) != 0) | |
612 | + { | |
613 | + warning (0, "%qs appears to be a misspelled nmi handler", | |
614 | + func_name); | |
615 | + } | |
616 | + } | |
617 | } | |
618 | ||
619 | return NULL_TREE; | |
40dfa9e4 | 620 | @@ -4994,7 +5257,8 @@ |
2bc38036 | 621 | /* fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);*/ |
622 | fputs ("__SREG__ = 0x3f\n" | |
623 | "__SP_H__ = 0x3e\n" | |
624 | - "__SP_L__ = 0x3d\n", asm_out_file); | |
625 | + "__SP_L__ = 0x3d\n" | |
626 | + "__CCP__ = 0x34\n", asm_out_file); | |
627 | ||
628 | fputs ("__tmp_reg__ = 0\n" | |
629 | "__zero_reg__ = 1\n", asm_out_file); | |
40dfa9e4 | 630 | @@ -5888,15 +6152,18 @@ |
2bc38036 | 631 | return !(regno & 1); |
632 | } | |
633 | ||
634 | -/* Returns 1 if X is a valid address for an I/O register of size SIZE | |
635 | - (1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE | |
636 | - to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */ | |
637 | +/* Returns 1 if X is a valid address for an I/O register of size SIZE | |
638 | + (1 or 2). Used for lds/sts -> in/out optimization. */ | |
639 | ||
640 | int | |
641 | avr_io_address_p (rtx x, int size) | |
642 | { | |
643 | - return (optimize > 0 && GET_CODE (x) == CONST_INT | |
644 | - && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size); | |
645 | + if(AVR_XMEGA) | |
646 | + return (optimize > 0 && GET_CODE (x) == CONST_INT | |
647 | + && INTVAL (x) >= 0 && INTVAL (x) <= 0x40 - size); | |
648 | + else | |
649 | + return (optimize > 0 && GET_CODE (x) == CONST_INT | |
650 | + && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size); | |
651 | } | |
652 | ||
653 | const char * | |
40dfa9e4 | 654 | @@ -6074,16 +6341,17 @@ |
2bc38036 | 655 | |
656 | if (GET_CODE (operands[1]) == CONST_INT) | |
657 | { | |
658 | - if (INTVAL (operands[1]) < 0x40) | |
659 | + operands[4] = GEN_INT(AVR_IO_OFFSET); /* operands[3] is for the jump */ | |
660 | + if (low_io_address_operand (operands[1], VOIDmode)) | |
661 | { | |
662 | if (comp == EQ) | |
663 | - output_asm_insn (AS2 (sbis,%1-0x20,%2), operands); | |
664 | + output_asm_insn (AS2 (sbis,%1-%4,%2), operands); | |
665 | else | |
666 | - output_asm_insn (AS2 (sbic,%1-0x20,%2), operands); | |
667 | + output_asm_insn (AS2 (sbic,%1-%4,%2), operands); | |
668 | } | |
669 | else | |
670 | { | |
671 | - output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands); | |
672 | + output_asm_insn (AS2 (in,__tmp_reg__,%1-%4), operands); | |
673 | if (comp == EQ) | |
674 | output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands); | |
675 | else | |
40dfa9e4 | 676 | --- ./gcc/config/avr/avr.h.orig 2010-03-08 12:55:09.000000000 +0100 |
677 | +++ ./gcc/config/avr/avr.h 2010-03-08 12:55:36.000000000 +0100 | |
678 | @@ -44,8 +44,11 @@ | |
2bc38036 | 679 | /* Core have 'EICALL' and 'EIJMP' instructions. */ |
680 | int have_eijmp_eicall; | |
681 | ||
682 | - /* Reserved. */ | |
683 | - int reserved; | |
684 | + /* Core is in Xmega family. */ | |
685 | + int xmega; | |
686 | + | |
687 | + /* Core have RAMPX, RAMPY and RAMPD registers. */ | |
688 | + int have_rampx_y_d; | |
689 | ||
690 | const char *const macro; | |
691 | }; | |
40dfa9e4 | 692 | @@ -68,6 +71,13 @@ |
2bc38036 | 693 | builtin_define ("__AVR_HAVE_ELPMX__"); \ |
694 | if (avr_have_movw_lpmx_p) \ | |
695 | builtin_define ("__AVR_HAVE_MOVW__"); \ | |
696 | + if (avr_current_arch->have_elpm) \ | |
697 | + { \ | |
698 | + builtin_define ("__AVR_HAVE_RAMPZ__");\ | |
699 | + builtin_define ("__AVR_HAVE_ELPM__"); \ | |
700 | + } \ | |
701 | + if (avr_current_arch->have_elpmx) \ | |
702 | + builtin_define ("__AVR_HAVE_ELPMX__"); \ | |
703 | if (avr_have_movw_lpmx_p) \ | |
704 | builtin_define ("__AVR_HAVE_LPMX__"); \ | |
705 | if (avr_asm_only_p) \ | |
40dfa9e4 | 706 | @@ -88,6 +98,17 @@ |
2bc38036 | 707 | builtin_define ("__AVR_HAVE_EIJMP_EICALL__"); \ |
708 | if (TARGET_NO_INTERRUPTS) \ | |
709 | builtin_define ("__NO_INTERRUPTS__"); \ | |
710 | + if (avr_current_arch->xmega) \ | |
711 | + { \ | |
712 | + builtin_define ("__AVR_XMEGA__"); \ | |
713 | + builtin_define ("__AVR_HAVE_SPMX__"); \ | |
714 | + } \ | |
715 | + if (avr_current_arch->have_rampx_y_d) \ | |
716 | + { \ | |
717 | + builtin_define ("__AVR_HAVE_RAMPX__");\ | |
718 | + builtin_define ("__AVR_HAVE_RAMPY__");\ | |
719 | + builtin_define ("__AVR_HAVE_RAMPD__");\ | |
720 | + } \ | |
721 | } \ | |
722 | while (0) | |
723 | ||
40dfa9e4 | 724 | @@ -107,10 +128,19 @@ |
2bc38036 | 725 | #define AVR_HAVE_LPMX (avr_have_movw_lpmx_p) |
726 | #define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm) | |
727 | #define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall) | |
728 | +#define AVR_XMEGA (avr_current_arch->xmega) | |
40dfa9e4 | 729 | +#define AVR_HAVE_RAMPX_Y_D (avr_current_arch->have_rampx_y_d) |
2bc38036 | 730 | |
731 | #define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL) | |
732 | #define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL) | |
733 | ||
734 | +#define AVR_IO_OFFSET (AVR_XMEGA ? 0 : 0x20) | |
40dfa9e4 | 735 | +#define AVR_RAMPD_ADDR (AVR_XMEGA ? 0x38 : 0) |
736 | +#define AVR_RAMPX_ADDR (AVR_XMEGA ? 0x39 : 0) | |
737 | +#define AVR_RAMPY_ADDR (AVR_XMEGA ? 0x3A : 0) | |
2bc38036 | 738 | +#define AVR_RAMPZ_ADDR (AVR_XMEGA ? 0x3B : 0x5B) |
739 | +#define AVR_SREG_ADDR (AVR_XMEGA ? 0x3F: 0x5F) | |
740 | + | |
741 | #define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)"); | |
742 | ||
743 | #define OVERRIDE_OPTIONS avr_override_options () | |
40dfa9e4 | 744 | @@ -935,6 +965,20 @@ |
745 | mmcu=m3000*|\ | |
746 | mmcu=m3001*: -m avr5}\ | |
2bc38036 | 747 | %{mmcu=atmega256*:-m avr6}\ |
40dfa9e4 | 748 | +%{mmcu=atxmega16a4|\ |
749 | + mmcu=atxmega16d4|\ | |
750 | + mmcu=atxmega32d4:-m avrxmega2}\ | |
751 | +%{mmcu=atxmega32a4:-m avrxmega3} \ | |
752 | +%{mmcu=atxmega64a3|\ | |
753 | + mmcu=atxmega64d3:-m avrxmega4} \ | |
2bc38036 | 754 | +%{mmcu=atxmega64a1:-m avrxmega5} \ |
40dfa9e4 | 755 | +%{mmcu=atxmega128a3|\ |
756 | + mmcu=atxmega128d3|\ | |
757 | + mmcu=atxmega192a3|\ | |
758 | + mmcu=atxmega192d3|\ | |
759 | + mmcu=atxmega256a3*|\ | |
760 | + mmcu=atxmega256d3:-m avrxmega6} \ | |
2bc38036 | 761 | +%{mmcu=atxmega128a1:-m avrxmega7} \ |
40dfa9e4 | 762 | %{mmcu=atmega324a|\ |
763 | mmcu=atmega324p|\ | |
764 | mmcu=atmega324pa|\ | |
765 | @@ -1190,7 +1234,22 @@ | |
766 | %{mmcu=m3000s:crtm3000s.o%s} \ | |
767 | %{mmcu=m3001b:crtm3001b.o%s} \ | |
768 | %{mmcu=atmega2560|mmcu=avr6:crtm2560.o%s} \ | |
769 | -%{mmcu=atmega2561:crtm2561.o%s}" | |
770 | +%{mmcu=atmega2561:crtm2561.o%s} \ | |
771 | +%{mmcu=avrxmega2|mmcu=atxmega32d4:crtx32d4.o%s} \ | |
772 | +%{mmcu=atxmega16a4:crtx16a4.o%s} \ | |
773 | +%{mmcu=atxmega16d4:crtx16d4.o%s} \ | |
774 | +%{mmcu=atxmega3|mmcu=atxmega32a4:crtx32a4.o%s} \ | |
775 | +%{mmcu=atxmega4|mmcu=atxmega64a3:crtx64a3.o%s} \ | |
776 | +%{mmcu=atxmega64d3:crtx64d3.o%s} \ | |
2bc38036 | 777 | +%{mmcu=atxmega5|mmcu=atxmega64a1:crtx64a1.o%s} \ |
40dfa9e4 | 778 | +%{mmcu=atxmega6|mmcu=atxmega128a3:crtx128a3.o%s} \ |
779 | +%{mmcu=atxmega128d3:crtx128d3.o%s}\ | |
780 | +%{mmcu=atxmega192a3:crtx192a3.o%s}\ | |
781 | +%{mmcu=atxmega192d3:crtx192d3.o%s}\ | |
782 | +%{mmcu=atxmega256a3:crtx256a3.o%s} \ | |
783 | +%{mmcu=atxmega256a3b:crtx256a3b.o%s} \ | |
784 | +%{mmcu=atxmega256d3:crtx256d3.o%s} \ | |
2bc38036 | 785 | +%{mmcu=atxmega7|mmcu=atxmega128a1:crtx128a1.o%s}" |
786 | ||
787 | #define EXTRA_SPECS {"crt_binutils", CRT_BINUTILS_SPECS}, | |
788 | ||
40dfa9e4 | 789 | @@ -1252,8 +1311,12 @@ |
2bc38036 | 790 | /* 'true' - if current function is a signal function |
791 | as specified by the "signal" attribute. */ | |
792 | int is_signal; | |
793 | - | |
794 | + | |
795 | /* 'true' - if current function is a signal function | |
796 | + as specified by the "nmi" attribute. */ | |
797 | + int is_nmi; | |
798 | + | |
799 | + /* 'true' - if current function is a task function | |
800 | as specified by the "OS_task" attribute. */ | |
801 | int is_OS_task; | |
802 | }; | |
40dfa9e4 | 803 | --- ./gcc/config/avr/t-avr.orig 2010-03-08 12:55:09.000000000 +0100 |
804 | +++ ./gcc/config/avr/t-avr 2010-03-08 12:55:36.000000000 +0100 | |
805 | @@ -37,8 +37,8 @@ | |
806 | ||
807 | FPBIT = fp-bit.c | |
808 | ||
809 | -MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6 | |
810 | -MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 | |
811 | +MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega3/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7 | |
812 | +MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 | |
813 | ||
814 | # The many avr2 matches are not listed here - this is the default. | |
815 | MULTILIB_MATCHES = \ | |
816 | @@ -182,7 +182,22 @@ | |
817 | mmcu?avr51=mmcu?m3000s \ | |
818 | mmcu?avr51=mmcu?m3001b \ | |
819 | mmcu?avr6=mmcu?atmega2560 \ | |
820 | - mmcu?avr6=mmcu?atmega2561 | |
821 | + mmcu?avr6=mmcu?atmega2561 \ | |
822 | + mmcu?avrxmega2=mmcu?atxmega16a4 \ | |
823 | + mmcu?avrxmega2=mmcu?atxmega16d4 \ | |
824 | + mmcu?avrxmega2=mmcu?atxmega32d4 \ | |
825 | + mmcu?avrxmega3=mmcu?atxmega32a4 \ | |
826 | + mmcu?avrxmega4=mmcu?atxmega64a3 \ | |
827 | + mmcu?avrxmega4=mmcu?atxmega64d3 \ | |
828 | + mmcu?avrxmega5=mmcu?atxmega64a1 \ | |
829 | + mmcu?avrxmega6=mmcu?atxmega128a3 \ | |
830 | + mmcu?avrxmega6=mmcu?atxmega128d3 \ | |
831 | + mmcu?avrxmega6=mmcu?atxmega192a3 \ | |
832 | + mmcu?avrxmega6=mmcu?atxmega192d3 \ | |
833 | + mmcu?avrxmega6=mmcu?atxmega256a3 \ | |
834 | + mmcu?avrxmega6=mmcu?atxmega256a3b \ | |
835 | + mmcu?avrxmega6=mmcu?atxmega256d3 \ | |
836 | + mmcu?avrxmega7=mmcu?atxmega128a1 | |
837 | MULTILIB_EXCEPTIONS = | |
838 | ||
839 | LIBGCC = stmp-multilib | |
840 | --- ./gcc/config/avr/avr.md.orig 2010-03-08 12:54:57.000000000 +0100 | |
841 | +++ ./gcc/config/avr/avr.md 2010-03-08 12:55:36.000000000 +0100 | |
2bc38036 | 842 | @@ -47,9 +47,6 @@ |
843 | (TMP_REGNO 0) ; temporary register r0 | |
844 | (ZERO_REGNO 1) ; zero register r1 | |
845 | ||
846 | - (SREG_ADDR 0x5F) | |
847 | - (RAMPZ_ADDR 0x5B) | |
848 | - | |
849 | (UNSPEC_STRLEN 0) | |
850 | (UNSPEC_INDEX_JMP 1) | |
40dfa9e4 | 851 | (UNSPEC_SWAP 2) |
852 | @@ -2677,7 +2674,8 @@ | |
2bc38036 | 853 | "(optimize > 0)" |
854 | { | |
855 | operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff)); | |
856 | - return AS2 (cbi,%0-0x20,%2); | |
857 | + operands[3] = GEN_INT(AVR_IO_OFFSET); | |
858 | + return AS2 (cbi,%0-%3,%2); | |
859 | } | |
860 | [(set_attr "length" "1") | |
861 | (set_attr "cc" "none")]) | |
40dfa9e4 | 862 | @@ -2689,7 +2687,8 @@ |
2bc38036 | 863 | "(optimize > 0)" |
864 | { | |
865 | operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff)); | |
866 | - return AS2 (sbi,%0-0x20,%2); | |
867 | + operands[3] = GEN_INT(AVR_IO_OFFSET); | |
868 | + return AS2 (sbi,%0-%3,%2); | |
869 | } | |
870 | [(set_attr "length" "1") | |
871 | (set_attr "cc" "none")]) | |
40dfa9e4 | 872 | --- ./gcc/config/avr/predicates.md.orig 2010-03-08 12:54:57.000000000 +0100 |
873 | +++ ./gcc/config/avr/predicates.md 2010-03-08 12:55:36.000000000 +0100 | |
874 | @@ -50,12 +50,16 @@ | |
2bc38036 | 875 | ;; Return true if OP is a valid address for lower half of I/O space. |
876 | (define_predicate "low_io_address_operand" | |
877 | (and (match_code "const_int") | |
878 | - (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)"))) | |
879 | + (if_then_else (match_test "AVR_XMEGA") | |
880 | + (match_test "IN_RANGE((INTVAL (op)), 0x00, 0x1F)") | |
881 | + (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)")))) | |
882 | ||
883 | ;; Return true if OP is a valid address for high half of I/O space. | |
884 | (define_predicate "high_io_address_operand" | |
885 | (and (match_code "const_int") | |
886 | - (match_test "IN_RANGE((INTVAL (op)), 0x40, 0x5F)"))) | |
887 | + (if_then_else (match_test "AVR_XMEGA") | |
888 | + (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)") | |
889 | + (match_test "IN_RANGE((INTVAL (op)), 0x40, 0x5F)")))) | |
890 | ||
891 | ;; Return 1 if OP is the zero constant for MODE. | |
892 | (define_predicate "const0_operand" |