]> git.pld-linux.org Git - packages/crossavr-gcc.git/blame - 301-gcc-4.5.1-xmega-v14.patch
- synchronized patches with Atmel official AVR8-GNU toolchain.
[packages/crossavr-gcc.git] / 301-gcc-4.5.1-xmega-v14.patch
CommitLineData
dbe7ab63 1diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
2--- gcc/config/avr/avr.c 2011-09-02 11:40:55.000000000 +0300
3+++ gcc/config/avr/avr.c 2011-09-02 11:40:01.000000000 +0300
4@@ -52,6 +52,7 @@
5 static int avr_naked_function_p (tree);
6 static int interrupt_function_p (tree);
7 static int signal_function_p (tree);
8+static int nmi_function_p (tree);
9 static int avr_OS_task_function_p (tree);
10 static int avr_OS_main_function_p (tree);
11 static int avr_regs_to_save (HARD_REG_SET *);
12@@ -122,6 +123,7 @@ static const struct attribute_spec avr_a
13 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute },
14 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
15 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
16+ { "nmi", 0, 0, true, false, false, avr_handle_fndecl_attribute },
17 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute },
18 { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute },
19 { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute },
20@@ -314,6 +316,21 @@ signal_function_p (tree func)
21 return a != NULL_TREE;
22 }
23
24+/* Return nonzero if FUNC is a nmi function as specified
25+ by the "nmi" attribute. */
26+
27+static int
28+nmi_function_p (tree func)
29+{
30+ tree a;
31+
32+ if (TREE_CODE (func) != FUNCTION_DECL)
33+ return 0;
34+
35+ a = lookup_attribute ("nmi", DECL_ATTRIBUTES (func));
36+ return a != NULL_TREE;
37+}
38+
39 /* Return nonzero if FUNC is a OS_task function. */
40
41 static int
42@@ -543,6 +560,7 @@ expand_prologue (void)
43 cfun->machine->is_naked = avr_naked_function_p (current_function_decl);
44 cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
45 cfun->machine->is_signal = signal_function_p (current_function_decl);
46+ cfun->machine->is_nmi = nmi_function_p (current_function_decl);
47 cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
48 cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
49 cfun->machine->stack_usage = 0;
50@@ -583,18 +601,49 @@ expand_prologue (void)
51
52 /* Push SREG. */
53 insn = emit_move_insn (tmp_reg_rtx,
54- gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
55+ gen_rtx_MEM (QImode, GEN_INT (AVR_SREG_ADDR)));
56 RTX_FRAME_RELATED_P (insn) = 1;
57 insn = emit_move_insn (pushbyte, tmp_reg_rtx);
58 RTX_FRAME_RELATED_P (insn) = 1;
59 cfun->machine->stack_usage++;
60
61+ /* Push RAMPD, RAMPX, RAMPY. */
62+ if (AVR_HAVE_RAMPX_Y_D)
63+ {
64+ /* Push RAMPD. */
65+ insn = emit_move_insn (tmp_reg_rtx,
66+ gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPD_ADDR)));
67+ RTX_FRAME_RELATED_P (insn) = 1;
68+ insn = emit_move_insn (pushbyte, tmp_reg_rtx);
69+ RTX_FRAME_RELATED_P (insn) = 1;
70+
71+ /* Push RAMPX. */
72+ if (TEST_HARD_REG_BIT (set, REG_X) && TEST_HARD_REG_BIT (set, REG_X + 1))
73+ {
74+ insn = emit_move_insn (tmp_reg_rtx,
75+ gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPX_ADDR)));
76+ RTX_FRAME_RELATED_P (insn) = 1;
77+ insn = emit_move_insn (pushbyte, tmp_reg_rtx);
78+ RTX_FRAME_RELATED_P (insn) = 1;
79+ }
80+
81+ /* Push RAMPY. */
82+ if (TEST_HARD_REG_BIT (set, REG_Y) && TEST_HARD_REG_BIT (set, REG_Y + 1))
83+ {
84+ insn = emit_move_insn (tmp_reg_rtx,
85+ gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPY_ADDR)));
86+ RTX_FRAME_RELATED_P (insn) = 1;
87+ insn = emit_move_insn (pushbyte, tmp_reg_rtx);
88+ RTX_FRAME_RELATED_P (insn) = 1;
89+ }
90+ }
91+
92 /* Push RAMPZ. */
93 if(AVR_HAVE_RAMPZ
94 && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
95 {
96 insn = emit_move_insn (tmp_reg_rtx,
97- gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
98+ gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPZ_ADDR)));
99 RTX_FRAME_RELATED_P (insn) = 1;
100 insn = emit_move_insn (pushbyte, tmp_reg_rtx);
101 RTX_FRAME_RELATED_P (insn) = 1;
102@@ -607,6 +656,41 @@ expand_prologue (void)
103
104 /* Prevent any attempt to delete the setting of ZERO_REG! */
105 emit_use (zero_reg_rtx);
106+
107+
108+ /*
109+ Clear RAMP? registers if used for data access in the interrupt/signal
110+ context. Do this after the zero register has been explictly cleared.
111+ */
112+ if (AVR_HAVE_RAMPX_Y_D)
113+ {
114+ /* Set RAMPD to 0. */
115+ insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPD_ADDR)), const0_rtx);
116+ RTX_FRAME_RELATED_P (insn) = 1;
117+
118+ if (TEST_HARD_REG_BIT (set, REG_X) && TEST_HARD_REG_BIT (set, REG_X + 1))
119+ {
120+ /* Set RAMPX to 0. */
121+ insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPX_ADDR)), const0_rtx);
122+ RTX_FRAME_RELATED_P (insn) = 1;
123+ }
124+
125+ if (TEST_HARD_REG_BIT (set, REG_Y) && TEST_HARD_REG_BIT (set, REG_Y + 1))
126+ {
127+ /* Set RAMPY to 0. */
128+ insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPY_ADDR)), const0_rtx);
129+ RTX_FRAME_RELATED_P (insn) = 1;
130+ }
131+
132+ if(AVR_HAVE_RAMPZ
133+ && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
134+ {
135+ /* Set RAMPZ to 0. */
136+ insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPZ_ADDR)), const0_rtx);
137+ RTX_FRAME_RELATED_P (insn) = 1;
138+ }
139+ }
140+
141 }
142 if (minimize && (frame_pointer_needed
143 || (AVR_2_BYTE_PC && live_seq > 6)
144@@ -698,16 +782,16 @@ expand_prologue (void)
145 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
146 RTX_FRAME_RELATED_P (insn) = 1;
147 }
148- else if (TARGET_NO_INTERRUPTS
149- || cfun->machine->is_signal
150- || cfun->machine->is_OS_main)
151+ else if ((!AVR_XMEGA && TARGET_NO_INTERRUPTS)
152+ || (!AVR_XMEGA && cfun->machine->is_signal)
153+ || (!AVR_XMEGA && cfun->machine->is_OS_main))
154 {
155 insn =
156 emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx,
157 frame_pointer_rtx));
158 RTX_FRAME_RELATED_P (insn) = 1;
159 }
160- else if (cfun->machine->is_interrupt)
161+ else if (!AVR_XMEGA && cfun->machine->is_interrupt)
162 {
163 insn = emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx,
164 frame_pointer_rtx));
165@@ -878,13 +962,13 @@ expand_epilogue (void)
166 {
167 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
168 }
169- else if (TARGET_NO_INTERRUPTS
170- || cfun->machine->is_signal)
171+ else if ((!AVR_XMEGA && TARGET_NO_INTERRUPTS)
172+ || (!AVR_XMEGA && cfun->machine->is_signal))
173 {
174 emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx,
175 frame_pointer_rtx));
176 }
177- else if (cfun->machine->is_interrupt)
178+ else if (!AVR_XMEGA && cfun->machine->is_interrupt)
179 {
180 emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx,
181 frame_pointer_rtx));
182@@ -937,14 +1021,39 @@ expand_epilogue (void)
183 && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
184 {
185 emit_insn (gen_popqi (tmp_reg_rtx));
186- emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(RAMPZ_ADDR)),
187+ emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(AVR_RAMPZ_ADDR)),
188+ tmp_reg_rtx);
189+ }
190+
191+ /* Restore RAMPY, RAMPX, RAMPD using tmp reg as scratch. */
192+ if (AVR_HAVE_RAMPX_Y_D)
193+ {
194+ /* Pop RAMPY. */
195+ if (TEST_HARD_REG_BIT (set, REG_Y) && TEST_HARD_REG_BIT (set, REG_Y + 1))
196+ {
197+ emit_insn (gen_popqi (tmp_reg_rtx));
198+ emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPY_ADDR)),
199+ tmp_reg_rtx);
200+ }
201+
202+ /* Pop RAMPX. */
203+ if (TEST_HARD_REG_BIT (set, REG_X) && TEST_HARD_REG_BIT (set, REG_X + 1))
204+ {
205+ emit_insn (gen_popqi (tmp_reg_rtx));
206+ emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPX_ADDR)),
207+ tmp_reg_rtx);
208+ }
209+
210+ /* Pop RAMPD. */
211+ emit_insn (gen_popqi (tmp_reg_rtx));
212+ emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPD_ADDR)),
213 tmp_reg_rtx);
214 }
215
216 /* Restore SREG using tmp reg as scratch. */
217 emit_insn (gen_popqi (tmp_reg_rtx));
218
219- emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)),
220+ emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(AVR_SREG_ADDR)),
221 tmp_reg_rtx);
222
223 /* Restore tmp REG. */
224@@ -1722,9 +1831,17 @@ output_movhi (rtx insn, rtx operands[],
225 return *l = 1, AS2 (out,__SP_L__,%A1);
226 /* Use simple load of stack pointer if no interrupts are
227 used. */
228- else if (TARGET_NO_INTERRUPTS)
229+ else if (!AVR_XMEGA && TARGET_NO_INTERRUPTS)
230 return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
231 AS2 (out,__SP_L__,%A1));
232+ if(AVR_XMEGA)
233+ {
234+ *l = 2;
235+ return (AS2 (out,__SP_L__,%A1) CR_TAB
236+ AS2 (out,__SP_H__,%B1));
237+ }
238+ else
239+ {
240 *l = 5;
241 return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
242 "cli" CR_TAB
243@@ -1732,6 +1849,7 @@ output_movhi (rtx insn, rtx operands[],
244 AS2 (out,__SREG__,__tmp_reg__) CR_TAB
245 AS2 (out,__SP_L__,%A1));
246 }
247+ }
248 else if (test_hard_reg_class (STACK_REG, src))
249 {
250 *l = 2;
251@@ -1865,7 +1983,7 @@ out_movqi_r_mr (rtx insn, rtx op[], int
252
253 if (CONSTANT_ADDRESS_P (x))
254 {
255- if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
256+ if (CONST_INT_P (x) && INTVAL (x) == AVR_SREG_ADDR)
257 {
258 *l = 1;
259 return AS2 (in,%0,__SREG__);
260@@ -1873,7 +1991,8 @@ out_movqi_r_mr (rtx insn, rtx op[], int
261 if (optimize > 0 && io_address_operand (x, QImode))
262 {
263 *l = 1;
264- return AS2 (in,%0,%m1-0x20);
265+ op[2] = GEN_INT(AVR_IO_OFFSET);
266+ return AS2 (in,%0,%m1-%2);
267 }
268 *l = 2;
269 return AS2 (lds,%0,%m1);
270@@ -2061,8 +2180,9 @@ out_movhi_r_mr (rtx insn, rtx op[], int
271 if (optimize > 0 && io_address_operand (base, HImode))
272 {
273 *l = 2;
274- return (AS2 (in,%A0,%m1-0x20) CR_TAB
275- AS2 (in,%B0,%m1+1-0x20));
276+ op[2] = GEN_INT(AVR_IO_OFFSET);
277+ return (AS2 (in,%A0,%m1-%2) CR_TAB
278+ AS2 (in,%B0,%m1+1-%2));
279 }
280 *l = 4;
281 return (AS2 (lds,%A0,%m1) CR_TAB
282@@ -2561,7 +2681,7 @@ out_movqi_mr_r (rtx insn, rtx op[], int
283
284 if (CONSTANT_ADDRESS_P (x))
285 {
286- if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
287+ if (CONST_INT_P (x) && INTVAL (x) == AVR_SREG_ADDR)
288 {
289 *l = 1;
290 return AS2 (out,__SREG__,%1);
291@@ -2569,7 +2689,8 @@ out_movqi_mr_r (rtx insn, rtx op[], int
292 if (optimize > 0 && io_address_operand (x, QImode))
293 {
294 *l = 1;
295- return AS2 (out,%m0-0x20,%1);
296+ op[2] = GEN_INT(AVR_IO_OFFSET);
297+ return AS2 (out,%m0-%2,%1);
298 }
299 *l = 2;
300 return AS2 (sts,%m0,%1);
301@@ -2648,9 +2769,18 @@ out_movhi_mr_r (rtx insn, rtx op[], int
302 if (optimize > 0 && io_address_operand (base, HImode))
303 {
304 *l = 2;
305- return (AS2 (out,%m0+1-0x20,%B1) CR_TAB
306- AS2 (out,%m0-0x20,%A1));
307+ op[2] = GEN_INT(AVR_IO_OFFSET);
308+ if (AVR_XMEGA)
309+ return (AS2 (out,%A0-%2,%A1) CR_TAB
310+ AS2 (out,%B0-%2,%B1));
311+ else
312+ return (AS2 (out,%m0+1-%2,%B1) CR_TAB
313+ AS2 (out,%m0-%2,%A1));
314 }
315+ if (AVR_XMEGA)
316+ return *l = 4, (AS2 (sts,%A0,%A1) CR_TAB
317+ AS2 (sts,%B0,%B1));
318+ else
319 return *l = 4, (AS2 (sts,%m0+1,%B1) CR_TAB
320 AS2 (sts,%m0,%A1));
321 }
322@@ -2667,11 +2797,20 @@ out_movhi_mr_r (rtx insn, rtx op[], int
323 AS2 (adiw,r26,1) CR_TAB
324 AS2 (st,X,__tmp_reg__));
325 else
326+ {
327+ if (!AVR_XMEGA)
328 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
329 AS2 (adiw,r26,1) CR_TAB
330 AS2 (st,X,__tmp_reg__) CR_TAB
331 AS2 (sbiw,r26,1) CR_TAB
332 AS2 (st,X,r26));
333+ else
334+ return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
335+ AS2 (st,X,r26) CR_TAB
336+ AS2 (adiw,r26,1) CR_TAB
337+ AS2 (st,X,__tmp_reg__) CR_TAB
338+ AS2 (sbiw,r26,1));
339+ }
340 }
341 else
342 {
343@@ -2679,14 +2818,27 @@ out_movhi_mr_r (rtx insn, rtx op[], int
344 return *l=2, (AS2 (st,X+,%A1) CR_TAB
345 AS2 (st,X,%B1));
346 else
347+ {
348+ if (!AVR_XMEGA)
349 return *l=3, (AS2 (adiw,r26,1) CR_TAB
350 AS2 (st,X,%B1) CR_TAB
351 AS2 (st,-X,%A1));
352+ else
353+ return *l=3, (AS2 (st,X+,%A1) CR_TAB
354+ AS2 (st,X,%B1) CR_TAB
355+ AS2 (sbiw,r26,1));
356+ }
357 }
358 }
359 else
360+ {
361+ if (!AVR_XMEGA)
362 return *l=2, (AS2 (std,%0+1,%B1) CR_TAB
363 AS2 (st,%0,%A1));
364+ else
365+ return *l=2, (AS2 (st,%0,%A1) CR_TAB
366+ AS2 (std,%0+1,%B1));
367+ }
368 }
369 else if (GET_CODE (base) == PLUS)
370 {
371@@ -2697,6 +2849,8 @@ out_movhi_mr_r (rtx insn, rtx op[], int
372 if (reg_base != REG_Y)
373 fatal_insn ("incorrect insn:",insn);
374
375+ if (!AVR_XMEGA)
376+ {
377 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
378 return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
379 AS2 (std,Y+63,%B1) CR_TAB
380@@ -2710,11 +2864,29 @@ out_movhi_mr_r (rtx insn, rtx op[], int
381 AS2 (subi,r28,lo8(%o0)) CR_TAB
382 AS2 (sbci,r29,hi8(%o0)));
383 }
384+ else
385+ {
386+ if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
387+ return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
388+ AS2 (std,Y+62,%A1) CR_TAB
389+ AS2 (std,Y+63,%B1) CR_TAB
390+ AS2 (sbiw,r28,%o0-62));
391+
392+ return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
393+ AS2 (sbci,r29,hi8(-%o0)) CR_TAB
394+ AS2 (st,Y,%A1) CR_TAB
395+ AS2 (std,Y+1,%B1) CR_TAB
396+ AS2 (subi,r28,lo8(%o0)) CR_TAB
397+ AS2 (sbci,r29,hi8(%o0)));
398+ }
399+ }
400 if (reg_base == REG_X)
401 {
402 /* (X + d) = R */
403 if (reg_src == REG_X)
404 {
405+ if (!AVR_XMEGA)
406+ {
407 *l = 7;
408 return (AS2 (mov,__tmp_reg__,r26) CR_TAB
409 AS2 (mov,__zero_reg__,r27) CR_TAB
410@@ -2724,21 +2896,57 @@ out_movhi_mr_r (rtx insn, rtx op[], int
411 AS1 (clr,__zero_reg__) CR_TAB
412 AS2 (sbiw,r26,%o0));
413 }
414+ else
415+ {
416+ *l = 7;
417+ return (AS2 (mov,__tmp_reg__,r26) CR_TAB
418+ AS2 (mov,__zero_reg__,r27) CR_TAB
419+ AS2 (adiw,r26,%o0) CR_TAB
420+ AS2 (st,X+,__tmp_reg__) CR_TAB
421+ AS2 (st,X,__zero_reg__) CR_TAB
422+ AS1 (clr,__zero_reg__) CR_TAB
423+ AS2 (sbiw,r26,%o0+1));
424+ }
425+ }
426+ if (!AVR_XMEGA)
427+ {
428 *l = 4;
429 return (AS2 (adiw,r26,%o0+1) CR_TAB
430 AS2 (st,X,%B1) CR_TAB
431 AS2 (st,-X,%A1) CR_TAB
432 AS2 (sbiw,r26,%o0));
433 }
434+ else
435+ {
436+ *l = 4;
437+ return (AS2 (adiw,r26,%o0) CR_TAB
438+ AS2 (st,X+,%A1) CR_TAB
439+ AS2 (st,X,%B1) CR_TAB
440+ AS2 (sbiw,r26,%o0+1));
441+ }
442+ }
443+
444+ if (!AVR_XMEGA)
445 return *l=2, (AS2 (std,%B0,%B1) CR_TAB
446 AS2 (std,%A0,%A1));
447+ else
448+ return *l=2, (AS2 (std,%A0,%A1) CR_TAB
449+ AS2 (std,%B0,%B1));
450 }
451 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
452+ {
453+ if (mem_volatile_p && AVR_XMEGA)
454+ return *l = 4, (AS2 (sbiw,%r0,2) CR_TAB
455+ AS2 (st,%p0+,%A1) CR_TAB
456+ AS2 (st,%p0,%B1) CR_TAB
457+ AS2 (sbiw,%r0,1));
458+ else
459 return *l=2, (AS2 (st,%0,%B1) CR_TAB
460 AS2 (st,%0,%A1));
461+ }
462 else if (GET_CODE (base) == POST_INC) /* (R++) */
463 {
464- if (mem_volatile_p)
465+ if (mem_volatile_p && !AVR_XMEGA)
466 {
467 if (REGNO (XEXP (base, 0)) == REG_X)
468 {
469@@ -4874,6 +5082,16 @@ avr_asm_declare_function_name (FILE *fil
470 }
471 }
472
473+ else if (cfun->machine->is_nmi)
474+ {
475+ if (strncmp (name, "__vector", strlen ("__vector")) != 0)
476+ {
477+ warning_at (DECL_SOURCE_LOCATION (decl), 0,
478+ "%qs appears to be a misspelled nmi handler",
479+ name);
480+ }
481+ }
482+
483 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
484 ASM_OUTPUT_LABEL (file, name);
485 }
486@@ -5174,7 +5392,8 @@ avr_file_start (void)
487 /* fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);*/
488 fputs ("__SREG__ = 0x3f\n"
489 "__SP_H__ = 0x3e\n"
490- "__SP_L__ = 0x3d\n", asm_out_file);
491+ "__SP_L__ = 0x3d\n"
492+ "__CCP__ = 0x34\n", asm_out_file);
493
494 fputs ("__tmp_reg__ = 0\n"
495 "__zero_reg__ = 1\n", asm_out_file);
496@@ -6273,16 +6492,17 @@ avr_out_sbxx_branch (rtx insn, rtx opera
497
498 if (GET_CODE (operands[1]) == CONST_INT)
499 {
500- if (INTVAL (operands[1]) < 0x40)
501+ operands[4] = GEN_INT(AVR_IO_OFFSET); /* operands[3] is for the jump */
502+ if (low_io_address_operand (operands[1], VOIDmode))
503 {
504 if (comp == EQ)
505- output_asm_insn (AS2 (sbis,%m1-0x20,%2), operands);
506+ output_asm_insn (AS2 (sbis,%1-%4,%2), operands);
507 else
508- output_asm_insn (AS2 (sbic,%m1-0x20,%2), operands);
509+ output_asm_insn (AS2 (sbic,%1-%4,%2), operands);
510 }
511 else
512 {
513- output_asm_insn (AS2 (in,__tmp_reg__,%m1-0x20), operands);
514+ output_asm_insn (AS2 (in,__tmp_reg__,%1-%4), operands);
515 if (comp == EQ)
516 output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
517 else
518diff -Naurp gcc/config/avr/avr-c.c gcc/config/avr/avr-c.c
519--- gcc/config/avr/avr-c.c 2009-12-24 23:32:38.000000000 +0300
520+++ gcc/config/avr/avr-c.c 2011-09-02 11:40:01.000000000 +0300
521@@ -81,5 +81,18 @@ avr_cpu_cpp_builtins (struct cpp_reader
522
523 if (TARGET_NO_INTERRUPTS)
524 cpp_define (pfile, "__NO_INTERRUPTS__");
525+
526+ if (avr_current_arch->xmega)
527+ {
528+ cpp_define (pfile, "__AVR_XMEGA__");
529+ cpp_define (pfile, "__AVR_HAVE_SPMX__");
530+ }
531+ if (avr_current_arch->have_rampx_y_d)
532+ {
533+ cpp_define (pfile, "__AVR_HAVE_RAMPX__");
534+ cpp_define (pfile, "__AVR_HAVE_RAMPY__");
535+ cpp_define (pfile, "__AVR_HAVE_RAMPD__");
536+ }
537+
538 }
539
540diff -Naurp gcc/config/avr/avr-devices.c gcc/config/avr/avr-devices.c
541--- gcc/config/avr/avr-devices.c 2009-07-17 21:49:03.000000000 +0300
542+++ gcc/config/avr/avr-devices.c 2011-09-02 11:42:48.000000000 +0300
543@@ -36,7 +36,14 @@ const struct base_arch_s avr_arch_types[
544 { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=4", "avr4" },
545 { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=5", "avr5" },
546 { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, "__AVR_ARCH__=51", "avr51" },
547- { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0x0060, "__AVR_ARCH__=6", "avr6" }
548+ { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0x0060, "__AVR_ARCH__=6", "avr6" },
549+ { 0, 1, 0, 1, 0, 0, 0, 1, 0, 0x2000, "__AVR_ARCH__=101", "avrxmega1" },
550+ { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0x2000, "__AVR_ARCH__=102", "avrxmega2" },
551+ { 0, 1, 1, 1, 0, 0, 0, 1, 1, 0x2000, "__AVR_ARCH__=103", "avrxmega3" },
552+ { 0, 1, 1, 1, 1, 1, 0, 1, 0, 0x2000, "__AVR_ARCH__=104", "avrxmega4" },
553+ { 0, 1, 1, 1, 1, 1, 0, 1, 1, 0x2000, "__AVR_ARCH__=105", "avrxmega5" },
554+ { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, "__AVR_ARCH__=106", "avrxmega6" },
555+ { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0x2000, "__AVR_ARCH__=107", "avrxmega7" }
556 };
557
558 /* List of all known AVR MCU types - if updated, it has to be kept
559@@ -189,6 +196,38 @@ const struct mcu_type_s avr_mcu_types[]
560 { "avr6", ARCH_AVR6, NULL, 0, 0x0200, "m2561" },
561 { "atmega2560", ARCH_AVR6, "__AVR_ATmega2560__", 0, 0x0200, "m2561" },
562 { "atmega2561", ARCH_AVR6, "__AVR_ATmega2561__", 0, 0x0200, "m2561" },
563+ /* Enhanced, == 256K. */
564+ /* Xmega, <= 8K FLASH. */
565+ /* Xmega, > 8K, <= 64K FLASH, <= 64K RAM. */
566+ { "avrxmega2", ARCH_AVRXMEGA2, NULL, 0, 0x2000, "x32a4" },
567+ { "atxmega16a4", ARCH_AVRXMEGA2, "__AVR_ATxmega16A4__", 0, 0x2000, "x16a4" },
568+ { "atxmega16d4", ARCH_AVRXMEGA2, "__AVR_ATxmega16D4__", 0, 0x2000, "x16d4" },
569+ { "atxmega16x1", ARCH_AVRXMEGA2, "__AVR_ATxmega16X1__", 0, 0x2000, "x16x1" },
570+ { "atxmega32a4", ARCH_AVRXMEGA2, "__AVR_ATxmega32A4__", 0, 0x2000, "x32a4" },
571+ { "atxmega32d4", ARCH_AVRXMEGA2, "__AVR_ATxmega32D4__", 0, 0x2000, "x32d4" },
572+ /* Xmega, > 8K, <= 64K FLASH, > 64K RAM. */
573+ /* { "avrxmega3", ARCH_AVRXMEGA3, NULL }, */
574+ /* Xmega, > 64K, <= 128K FLASH, <= 64K RAM. */
575+ { "avrxmega4", ARCH_AVRXMEGA4, NULL, 0, 0x2000, "x64d3" },
576+ { "atxmega64a3", ARCH_AVRXMEGA4, "__AVR_ATxmega64A3__", 0, 0x2000, "x64a3" },
577+ { "atxmega64d3", ARCH_AVRXMEGA4, "__AVR_ATxmega64D3__", 0, 0x2000, "x64d3" },
578+ /* Xmega, > 64K, <= 128K FLASH, > 64K RAM. */
579+ { "avrxmega5", ARCH_AVRXMEGA5, NULL, 0, 0x2000, "x64a1" },
580+ { "atxmega64a1", ARCH_AVRXMEGA5, "__AVR_ATxmega64A1__", 0, 0x2000, "x64a1" },
581+ { "atxmega64a1u", ARCH_AVRXMEGA5, "__AVR_ATxmega64A1U__", 0, 0x2000, "x64a1u" },
582+ /* Xmega, > 128K, <= 256K FLASH, <= 64K RAM. */
583+ { "avrxmega6", ARCH_AVRXMEGA6, NULL, 0, 0x2000, "x128a3" },
584+ { "atxmega128a3", ARCH_AVRXMEGA6, "__AVR_ATxmega128A3__", 0, 0x2000, "x128a3" },
585+ { "atxmega128d3", ARCH_AVRXMEGA6, "__AVR_ATxmega128D3__", 0, 0x2000, "x128d3" },
586+ { "atxmega192a3", ARCH_AVRXMEGA6, "__AVR_ATxmega192A3__", 0, 0x2000, "x192a3" },
587+ { "atxmega192d3", ARCH_AVRXMEGA6, "__AVR_ATxmega192D3__", 0, 0x2000, "x192d3" },
588+ { "atxmega256a3", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3__", 0, 0x2000, "x256a3" },
589+ { "atxmega256a3b",ARCH_AVRXMEGA6, "__AVR_ATxmega256A3B__", 0, 0x2000, "x256a3b" },
590+ { "atxmega256d3", ARCH_AVRXMEGA6, "__AVR_ATxmega256D3__", 0, 0x2000, "x256d3" },
591+ /* Xmega, > 128K, <= 256K FLASH, > 64K RAM. */
592+ { "avrxmega7", ARCH_AVRXMEGA7, NULL, 0, 0x2000, "x128a1" },
593+ { "atxmega128a1", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1__", 0, 0x2000, "x128a1" },
594+ { "atxmega128a1u", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1U__", 0, 0x2000, "x128a1u" },
595 /* Assembler only. */
596 { "avr1", ARCH_AVR1, NULL, 0, 0x0060, "s1200" },
597 { "at90s1200", ARCH_AVR1, "__AVR_AT90S1200__", 0, 0x0060, "s1200" },
598diff -Naurp gcc/config/avr/avr.h gcc/config/avr/avr.h
599--- gcc/config/avr/avr.h 2010-01-12 02:12:14.000000000 +0300
600+++ gcc/config/avr/avr.h 2011-09-02 11:40:01.000000000 +0300
601@@ -45,11 +45,11 @@ struct base_arch_s {
602 /* Core have 'EICALL' and 'EIJMP' instructions. */
603 int have_eijmp_eicall;
604
605- /* Reserved for xmega architecture. */
606- int reserved;
607+ /* Core is in Xmega family. */
608+ int xmega;
609
610- /* Reserved for xmega architecture. */
611- int reserved2;
612+ /* Core have RAMPX, RAMPY and RAMPD registers. */
613+ int have_rampx_y_d;
614
615 /* Default start of data section address for architecture. */
616 int default_data_section_start;
617@@ -75,7 +75,14 @@ enum avr_arch
618 ARCH_AVR4,
619 ARCH_AVR5,
620 ARCH_AVR51,
621- ARCH_AVR6
622+ ARCH_AVR6,
623+ ARCH_AVRXMEGA1,
624+ ARCH_AVRXMEGA2,
625+ ARCH_AVRXMEGA3,
626+ ARCH_AVRXMEGA4,
627+ ARCH_AVRXMEGA5,
628+ ARCH_AVRXMEGA6,
629+ ARCH_AVRXMEGA7
630 };
631
632 struct mcu_type_s {
633@@ -118,10 +125,18 @@ extern GTY(()) section *progmem_section;
634 #define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm)
635 #define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall)
636 #define AVR_HAVE_8BIT_SP (avr_current_device->short_sp || TARGET_TINY_STACK)
637+#define AVR_XMEGA (avr_current_arch->xmega)
638+#define AVR_HAVE_RAMPX_Y_D (avr_current_arch->have_rampx_y_d)
639
640 #define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL)
641 #define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL)
642
643+#define AVR_IO_OFFSET (AVR_XMEGA ? 0 : 0x20)
644+#define AVR_RAMPD_ADDR (AVR_XMEGA ? 0x38 : 0)
645+#define AVR_RAMPX_ADDR (AVR_XMEGA ? 0x39 : 0)
646+#define AVR_RAMPY_ADDR (AVR_XMEGA ? 0x3A : 0)
647+#define AVR_RAMPZ_ADDR (AVR_XMEGA ? 0x3B : 0x5B)
648+#define AVR_SREG_ADDR (AVR_XMEGA ? 0x3F: 0x5F)
649 #define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)");
650
651 #define OVERRIDE_OPTIONS avr_override_options ()
652@@ -842,6 +857,10 @@ struct GTY(()) machine_function
653 as specified by the "signal" attribute. */
654 int is_signal;
655
656+ /* 'true' - if current function is a signal function
657+ as specified by the "nmi" attribute. */
658+ int is_nmi;
659+
660 /* 'true' - if current function is a 'task' function
661 as specified by the "OS_task" attribute. */
662 int is_OS_task;
663diff -Naurp gcc/config/avr/avr.md gcc/config/avr/avr.md
664--- gcc/config/avr/avr.md 2011-09-02 11:40:55.000000000 +0300
665+++ gcc/config/avr/avr.md 2011-09-02 11:40:01.000000000 +0300
666@@ -49,9 +49,6 @@
667 (TMP_REGNO 0) ; temporary register r0
668 (ZERO_REGNO 1) ; zero register r1
669
670- (SREG_ADDR 0x5F)
671- (RAMPZ_ADDR 0x5B)
672-
673 (UNSPEC_STRLEN 0)
674 (UNSPEC_INDEX_JMP 1)
675 (UNSPEC_SEI 2)
676@@ -2962,7 +2959,8 @@
677 "(optimize > 0)"
678 {
679 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
680- return AS2 (cbi,%m0-0x20,%2);
681+ operands[3] = GEN_INT(AVR_IO_OFFSET);
682+ return AS2 (cbi,%0-%3,%2);
683 }
684 [(set_attr "length" "1")
685 (set_attr "cc" "none")])
686@@ -2974,7 +2972,8 @@
687 "(optimize > 0)"
688 {
689 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
690- return AS2 (sbi,%m0-0x20,%2);
691+ operands[3] = GEN_INT(AVR_IO_OFFSET);
692+ return AS2 (sbi,%0-%3,%2);
693 }
694 [(set_attr "length" "1")
695 (set_attr "cc" "none")])
696diff -Naurp gcc/config/avr/libgcc.S gcc/config/avr/libgcc.S
697--- gcc/config/avr/libgcc.S 2011-09-02 11:40:55.000000000 +0300
698+++ gcc/config/avr/libgcc.S 2011-09-02 11:40:01.000000000 +0300
699@@ -637,11 +637,19 @@ __prologue_saves__:
700 in r29,__SP_H__
701 sub r28,r26
702 sbc r29,r27
703+
704+/* Restore stack pointer. */
705+#if defined (__AVR_XMEGA__)
706+ out __SP_L__,r28
707+ out __SP_H__,r29
708+#else
709 in __tmp_reg__,__SREG__
710 cli
711 out __SP_H__,r29
712 out __SREG__,__tmp_reg__
713 out __SP_L__,r28
714+#endif
715+
716 #if defined (__AVR_HAVE_EIJMP_EICALL__)
717 eijmp
718 #else
719@@ -679,11 +687,18 @@ __epilogue_restores__:
720 ldd r27,Y+1
721 add r28,r30
722 adc r29,__zero_reg__
723+
724+/* Restore stack pointer. */
725+#if defined(__AVR_XMEGA__)
726+ out __SP_L__,r28
727+ out __SP_H__,r29
728+#else
729 in __tmp_reg__,__SREG__
730 cli
731 out __SP_H__,r29
732 out __SREG__,__tmp_reg__
733 out __SP_L__,r28
734+#endif
735 mov_l r28, r26
736 mov_h r29, r27
737 ret
738diff -Naurp gcc/config/avr/predicates.md gcc/config/avr/predicates.md
739--- gcc/config/avr/predicates.md 2009-12-24 22:53:57.000000000 +0300
740+++ gcc/config/avr/predicates.md 2011-09-02 11:40:01.000000000 +0300
741@@ -45,17 +45,23 @@
742 ;; Return true if OP is a valid address for lower half of I/O space.
743 (define_predicate "low_io_address_operand"
744 (and (match_code "const_int")
745- (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)")))
746+ (if_then_else (match_test "AVR_XMEGA")
747+ (match_test "IN_RANGE((INTVAL (op)), 0x00, 0x1F)")
748+ (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)"))))
749
750 ;; Return true if OP is a valid address for high half of I/O space.
751 (define_predicate "high_io_address_operand"
752 (and (match_code "const_int")
753- (match_test "IN_RANGE((INTVAL (op)), 0x40, 0x5F)")))
754+ (if_then_else (match_test "AVR_XMEGA")
755+ (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)")
756+ (match_test "IN_RANGE((INTVAL (op)), 0x40, 0x5F)"))))
757
758 ;; Return true if OP is a valid address of I/O space.
759 (define_predicate "io_address_operand"
760 (and (match_code "const_int")
761- (match_test "IN_RANGE((INTVAL (op)), 0x20, (0x60 - GET_MODE_SIZE(mode)))")))
762+ (if_then_else (match_test "AVR_XMEGA")
763+ (match_test "IN_RANGE((INTVAL (op)), 0x0, (0x40 - GET_MODE_SIZE(mode)))")
764+ (match_test "IN_RANGE((INTVAL (op)), 0x20, (0x60 - GET_MODE_SIZE(mode)))"))))
765
766 ;; Return 1 if OP is the zero constant for MODE.
767 (define_predicate "const0_operand"
768diff -Naurp gcc/config/avr/t-avr gcc/config/avr/t-avr
769--- gcc/config/avr/t-avr 2011-09-02 11:40:55.000000000 +0300
770+++ gcc/config/avr/t-avr 2011-09-02 11:41:56.000000000 +0300
771@@ -107,8 +107,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c $(sr
772
773 FPBIT = fp-bit.c
774
775-MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6
776-MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6
777+MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7
778+MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7
779
780 # The many avr2 matches are not listed here - this is the default.
781 MULTILIB_MATCHES = \
782@@ -223,7 +223,25 @@ MULTILIB_MATCHES = \
783 mmcu?avr51=mmcu?m3000s \
784 mmcu?avr51=mmcu?m3001b \
785 mmcu?avr6=mmcu?atmega2560 \
786- mmcu?avr6=mmcu?atmega2561
787+ mmcu?avr6=mmcu?atmega2561 \
788+ mmcu?avrxmega2=mmcu?atxmega16a4 \
789+ mmcu?avrxmega2=mmcu?atxmega16d4 \
790+ mmcu?avrxmega2=mmcu?atxmega16x1 \
791+ mmcu?avrxmega2=mmcu?atxmega32d4 \
792+ mmcu?avrxmega2=mmcu?atxmega32a4 \
793+ mmcu?avrxmega4=mmcu?atxmega64a3 \
794+ mmcu?avrxmega4=mmcu?atxmega64d3 \
795+ mmcu?avrxmega5=mmcu?atxmega64a1 \
796+ mmcu?avrxmega5=mmcu?atxmega64a1u \
797+ mmcu?avrxmega6=mmcu?atxmega128a3 \
798+ mmcu?avrxmega6=mmcu?atxmega128d3 \
799+ mmcu?avrxmega6=mmcu?atxmega192a3 \
800+ mmcu?avrxmega6=mmcu?atxmega192d3 \
801+ mmcu?avrxmega6=mmcu?atxmega256a3 \
802+ mmcu?avrxmega6=mmcu?atxmega256a3b \
803+ mmcu?avrxmega6=mmcu?atxmega256d3 \
804+ mmcu?avrxmega7=mmcu?atxmega128a1 \
805+ mmcu?avrxmega7=mmcu?atxmega128a1u
806
807 MULTILIB_EXCEPTIONS =
808
This page took 0.16321 seconds and 4 git commands to generate.