]> git.pld-linux.org Git - packages/crossavr-gcc.git/blame - crossavr-gcc-xmega.patch
- rel 2
[packages/crossavr-gcc.git] / crossavr-gcc-xmega.patch
CommitLineData
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"
This page took 0.168787 seconds and 4 git commands to generate.