diff --git a/devel/avr-gcc/Makefile b/devel/avr-gcc/Makefile index 6bc50a93d5ab..4a37609a41a1 100644 --- a/devel/avr-gcc/Makefile +++ b/devel/avr-gcc/Makefile @@ -7,7 +7,7 @@ PORTNAME= gcc PORTVERSION= 4.3.2 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= devel MASTER_SITES= ${MASTER_SITE_GCC} MASTER_SITES+= http://people.freebsd.org/~joerg/:local diff --git a/devel/avr-gcc/files/patch-xmega b/devel/avr-gcc/files/patch-xmega index b1913b8bca76..dea2f61001c6 100644 --- a/devel/avr-gcc/files/patch-xmega +++ b/devel/avr-gcc/files/patch-xmega @@ -1,197 +1,6 @@ ---- gcc/config/avr/avr.md.orig 2008-06-08 10:24:28.171355800 -0600 -+++ gcc/config/avr/avr.md 2008-06-08 10:29:58.610141800 -0600 -@@ -47,9 +47,6 @@ - (TMP_REGNO 0) ; temporary register r0 - (ZERO_REGNO 1) ; zero register r1 - -- (SREG_ADDR 0x5F) -- (RAMPZ_ADDR 0x5B) -- - (UNSPEC_STRLEN 0) - (UNSPEC_INDEX_JMP 1) - (UNSPEC_SEI 2) -@@ -2681,7 +2678,8 @@ - "(optimize > 0)" - { - operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff)); -- return AS2 (cbi,%0-0x20,%2); -+ operands[3] = GEN_INT(AVR_IO_OFFSET); -+ return AS2 (cbi,%0-%3,%2); - } - [(set_attr "length" "1") - (set_attr "cc" "none")]) -@@ -2693,7 +2691,8 @@ - "(optimize > 0)" - { - operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff)); -- return AS2 (sbi,%0-0x20,%2); -+ operands[3] = GEN_INT(AVR_IO_OFFSET); -+ return AS2 (sbi,%0-%3,%2); - } - [(set_attr "length" "1") - (set_attr "cc" "none")]) -Index: gcc/config/avr/predicates.md -=================================================================== ---- gcc/config/avr/predicates.md (revision 132445) -+++ gcc/config/avr/predicates.md (working copy) -@@ -45,12 +45,16 @@ - ;; Return true if OP is a valid address for lower half of I/O space. - (define_predicate "low_io_address_operand" - (and (match_code "const_int") -- (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)"))) -+ (if_then_else (match_test "AVR_XMEGA") -+ (match_test "IN_RANGE((INTVAL (op)), 0x00, 0x1F)") -+ (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)")))) - - ;; Return true if OP is a valid address for high half of I/O space. - (define_predicate "high_io_address_operand" - (and (match_code "const_int") -- (match_test "IN_RANGE((INTVAL (op)), 0x40, 0x5F)"))) -+ (if_then_else (match_test "AVR_XMEGA") -+ (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)") -+ (match_test "IN_RANGE((INTVAL (op)), 0x40, 0x5F)")))) - - ;; Return 1 if OP is the zero constant for MODE. - (define_predicate "const0_operand" ---- gcc/config/avr/t-avr.orig 2008-02-19 17:25:31.546827500 -0700 -+++ gcc/config/avr/t-avr 2008-02-20 09:22:51.709554900 -0700 -@@ -37,8 +37,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c $(sr - - FPBIT = fp-bit.c - --MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6 --MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 -+MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7 -+MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega4 avrxmega5 avrxmega6 avrxmega7 - - # The many avr2 matches are not listed here - this is the default. - MULTILIB_MATCHES = \ -@@ -125,7 +125,13 @@ MULTILIB_MATCHES = \ - mmcu?avr51=mmcu?at90usb1286 \ - mmcu?avr51=mmcu?at90usb1287 \ - mmcu?avr6=mmcu?atmega2560 \ -- mmcu?avr6=mmcu?atmega2561 -+ mmcu?avr6=mmcu?atmega2561 \ -+ mmcu?avrxmega4=mmcu?atxmega64a3 \ -+ mmcu?avrxmega5=mmcu?atxmega64a1 \ -+ mmcu?avrxmega6=mmcu?atxmega128a3 \ -+ mmcu?avrxmega6=mmcu?atxmega256a3 \ -+ mmcu?avrxmega6=mmcu?atxmega256a3b \ -+ mmcu?avrxmega7=mmcu?atxmega128a1 - - MULTILIB_EXCEPTIONS = - ---- gcc/config/avr/avr.h.orig 2009-01-26 17:47:48.000000000 +0100 -+++ gcc/config/avr/avr.h 2009-01-26 17:56:22.000000000 +0100 -@@ -44,8 +44,11 @@ - /* Core have 'EICALL' and 'EIJMP' instructions. */ - int have_eijmp_eicall; - -- /* Reserved. */ -- int reserved; -+ /* Core is in Xmega family. */ -+ int xmega; -+ -+ /* Core have RAMPX, RAMPY and RAMPD registers. */ -+ int have_rampx_y_d; - - const char *const macro; - }; -@@ -68,6 +71,13 @@ - builtin_define ("__AVR_HAVE_ELPMX__"); \ - if (avr_have_movw_lpmx_p) \ - builtin_define ("__AVR_HAVE_MOVW__"); \ -+ if (avr_current_arch->have_elpm) \ -+ { \ -+ builtin_define ("__AVR_HAVE_RAMPZ__");\ -+ builtin_define ("__AVR_HAVE_ELPM__"); \ -+ } \ -+ if (avr_current_arch->have_elpmx) \ -+ builtin_define ("__AVR_HAVE_ELPMX__"); \ - if (avr_have_movw_lpmx_p) \ - builtin_define ("__AVR_HAVE_LPMX__"); \ - if (avr_asm_only_p) \ -@@ -88,6 +98,17 @@ - builtin_define ("__AVR_HAVE_EIJMP_EICALL__"); \ - if (TARGET_NO_INTERRUPTS) \ - builtin_define ("__NO_INTERRUPTS__"); \ -+ if (avr_current_arch->xmega) \ -+ { \ -+ builtin_define ("__AVR_XMEGA__"); \ -+ builtin_define ("__AVR_HAVE_SPMX__"); \ -+ } \ -+ if (avr_current_arch->have_rampx_y_d) \ -+ { \ -+ builtin_define ("__AVR_HAVE_RAMPX__");\ -+ builtin_define ("__AVR_HAVE_RAMPY__");\ -+ builtin_define ("__AVR_HAVE_RAMPD__");\ -+ } \ - } \ - while (0) - -@@ -107,10 +128,19 @@ - #define AVR_HAVE_LPMX (avr_have_movw_lpmx_p) - #define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm) - #define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall) -+#define AVR_XMEGA (avr_current_arch->xmega) -+#define AVR_HAVE_RAMPX_Y_D (avr_current_arch->have_rampx_y_d) - - #define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL) - #define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL) - -+#define AVR_IO_OFFSET (AVR_XMEGA ? 0 : 0x20) -+#define AVR_RAMPD_ADDR (AVR_XMEGA ? 0x38 : 0) -+#define AVR_RAMPX_ADDR (AVR_XMEGA ? 0x39 : 0) -+#define AVR_RAMPY_ADDR (AVR_XMEGA ? 0x3A : 0) -+#define AVR_RAMPZ_ADDR (AVR_XMEGA ? 0x3B : 0x5B) -+#define AVR_SREG_ADDR (AVR_XMEGA ? 0x3F: 0x5F) -+ - #define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)"); - - #define OVERRIDE_OPTIONS avr_override_options () -@@ -848,6 +878,11 @@ - mmcu=m3000*|\ - mmcu=m3001*: -m avr5}\ - %{mmcu=atmega256*:-m avr6}\ -+%{mmcu=atxmega64a3:-m avrxmega4} \ -+%{mmcu=atxmega64a1:-m avrxmega5} \ -+%{mmcu=atxmega128a3| \ -+ mmcu=atxmega256a3*:-m avrxmega6} \ -+%{mmcu=atxmega128a1:-m avrxmega7} \ - %{mmcu=atmega324*|\ - mmcu=atmega325*|\ - mmcu=atmega328p|\ -@@ -1024,7 +1059,13 @@ - %{mmcu=m3000s:crtm3000s.o%s} \ - %{mmcu=m3001b:crtm3001b.o%s} \ - %{mmcu=atmega2560|mmcu=avr6:crtm2560.o%s} \ --%{mmcu=atmega2561:crtm2561.o%s}" -+%{mmcu=atmega2561:crtm2561.o%s} \ -+%{mmcu=atxmega4|mmcu=atxmega64a3:crtx64a3.o%s} \ -+%{mmcu=atxmega5|mmcu=atxmega64a1:crtx64a1.o%s} \ -+%{mmcu=atxmega6|mmcu=atxmega128a3:crtx128a3.o%s} \ -+%{mmcu=atxmega256a3:crtx256a3.o%s} \ -+%{mmcu=atxmega256a3b:crtx256a3b.o%s} \ -+%{mmcu=atxmega7|mmcu=atxmega128a1:crtx128a1.o%s}" - - #define EXTRA_SPECS {"crt_binutils", CRT_BINUTILS_SPECS}, - -@@ -1086,8 +1127,12 @@ - /* 'true' - if current function is a signal function - as specified by the "signal" attribute. */ - int is_signal; -- -+ - /* 'true' - if current function is a signal function -+ as specified by the "nmi" attribute. */ -+ int is_nmi; -+ -+ /* 'true' - if current function is a task function - as specified by the "OS_task" attribute. */ - int is_OS_task; - }; ---- gcc/config/avr/avr.c.orig 2009-01-26 17:44:48.000000000 +0100 -+++ gcc/config/avr/avr.c 2009-01-26 17:54:54.000000000 +0100 +diff -ur ../gcc-4.3.2.orig/gcc/config/avr/avr.c ./gcc/config/avr/avr.c +--- ../gcc-4.3.2.orig/gcc/config/avr/avr.c 2009-08-11 14:17:06.000000000 +0200 ++++ ./gcc/config/avr/avr.c 2009-08-11 14:38:44.000000000 +0200 @@ -51,6 +51,7 @@ static int avr_naked_function_p (tree); static int interrupt_function_p (tree); @@ -252,7 +61,7 @@ Index: gcc/config/avr/predicates.md }; struct mcu_type_s { -@@ -297,6 +312,24 @@ +@@ -297,6 +312,26 @@ { "avr6", ARCH_AVR6, NULL }, { "atmega2560", ARCH_AVR6, "__AVR_ATmega2560__" }, { "atmega2561", ARCH_AVR6, "__AVR_ATmega2561__" }, @@ -260,6 +69,8 @@ Index: gcc/config/avr/predicates.md + /* Xmega, <= 8K FLASH. */ + /* Xmega, > 8K, <= 64K FLASH, <= 64K RAM. */ + /* Xmega, > 8K, <= 64K FLASH, > 64K RAM. */ ++ { "avrxmega3", ARCH_AVRXMEGA3, NULL }, ++ { "atxmega32a4", ARCH_AVRXMEGA3, "__AVR_ATxmega32A4__" }, + /* Xmega, > 64K, <= 128K FLASH, <= 64K RAM. */ + { "avrxmega4", ARCH_AVRXMEGA4, NULL }, + { "atxmega64a3", ARCH_AVRXMEGA4, "__AVR_ATxmega64A3__" }, @@ -277,7 +88,7 @@ Index: gcc/config/avr/predicates.md /* Assembler only. */ { "avr1", ARCH_AVR1, NULL }, { "at90s1200", ARCH_AVR1, "__AVR_AT90S1200__" }, -@@ -470,6 +503,21 @@ +@@ -470,6 +505,21 @@ return a != NULL_TREE; } @@ -299,7 +110,7 @@ Index: gcc/config/avr/predicates.md /* Return nonzero if FUNC is a OS_task function. */ static int -@@ -629,6 +677,7 @@ +@@ -629,6 +679,7 @@ cfun->machine->is_naked = avr_naked_function_p (current_function_decl); cfun->machine->is_interrupt = interrupt_function_p (current_function_decl); cfun->machine->is_signal = signal_function_p (current_function_decl); @@ -307,7 +118,7 @@ Index: gcc/config/avr/predicates.md cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl); /* Prologue: naked. */ -@@ -664,17 +713,48 @@ +@@ -664,20 +715,78 @@ /* Push SREG. */ insn = emit_move_insn (tmp_reg_rtx, @@ -327,6 +138,11 @@ Index: gcc/config/avr/predicates.md + insn = emit_move_insn (pushbyte, tmp_reg_rtx); + RTX_FRAME_RELATED_P (insn) = 1; + ++ /* Set RAMPD to 0. */ ++ insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPD_ADDR)), ++ const0_rtx); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ + /* Push RAMPX. */ + if (TEST_HARD_REG_BIT (set, REG_X) && TEST_HARD_REG_BIT (set, REG_X + 1)) + { @@ -335,6 +151,11 @@ Index: gcc/config/avr/predicates.md + RTX_FRAME_RELATED_P (insn) = 1; + insn = emit_move_insn (pushbyte, tmp_reg_rtx); + RTX_FRAME_RELATED_P (insn) = 1; ++ ++ /* Set RAMPX to 0. */ ++ insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPX_ADDR)), ++ const0_rtx); ++ RTX_FRAME_RELATED_P (insn) = 1; + } + + /* Push RAMPY. */ @@ -345,6 +166,11 @@ Index: gcc/config/avr/predicates.md + RTX_FRAME_RELATED_P (insn) = 1; + insn = emit_move_insn (pushbyte, tmp_reg_rtx); + RTX_FRAME_RELATED_P (insn) = 1; ++ ++ /* Set RAMPY to 0. */ ++ insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPY_ADDR)), ++ const0_rtx); ++ RTX_FRAME_RELATED_P (insn) = 1; + } + } + @@ -358,7 +184,22 @@ Index: gcc/config/avr/predicates.md RTX_FRAME_RELATED_P (insn) = 1; insn = emit_move_insn (pushbyte, tmp_reg_rtx); RTX_FRAME_RELATED_P (insn) = 1; -@@ -949,14 +1029,39 @@ ++ ++ /* ++ Clearing the RAMPZ register is needed only if it is used for data ++ space access. ++ */ ++ if (AVR_HAVE_RAMPX_Y_D) ++ { ++ /* Set RAMPZ to 0. */ ++ insn = emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPZ_ADDR)), ++ const0_rtx); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ } + } + + /* Clear zero reg. */ +@@ -949,14 +1058,39 @@ && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1))) { emit_insn (gen_popqi (tmp_reg_rtx)); @@ -400,7 +241,7 @@ Index: gcc/config/avr/predicates.md tmp_reg_rtx); /* Restore tmp REG. */ -@@ -1725,8 +1830,9 @@ +@@ -1725,8 +1859,9 @@ } /* Use simple load of stack pointer if no interrupts are used or inside main or signal function prologue where they disabled. */ @@ -412,7 +253,7 @@ Index: gcc/config/avr/predicates.md && cfun->machine->is_signal && prologue_epilogue_contains (insn))) { -@@ -1735,7 +1841,8 @@ +@@ -1735,7 +1870,8 @@ AS2 (out,__SP_L__,%A1)); } /* In interrupt prolog we know interrupts are enabled. */ @@ -422,7 +263,7 @@ Index: gcc/config/avr/predicates.md && cfun->machine->is_interrupt && prologue_epilogue_contains (insn)) { -@@ -1745,12 +1852,25 @@ +@@ -1745,12 +1881,21 @@ "sei" CR_TAB AS2 (out,__SP_L__,%A1)); } @@ -434,13 +275,9 @@ Index: gcc/config/avr/predicates.md - AS2 (out,__SP_L__,%A1)); + if(AVR_XMEGA) + { -+ *l = 6; -+ return (AS2 (mov,__tmp_reg__,r24) CR_TAB -+ AS2 (ldi,r24,0xD8) CR_TAB -+ AS2 (out,__CCP__,r24) CR_TAB -+ AS2 (out,__SP_H__,%B1) CR_TAB -+ AS2 (out,__SP_L__,%A1) CR_TAB -+ AS2 (mov,r24,__tmp_reg__)); ++ *l = 2; ++ return (AS2 (out,__SP_L__,%A1) CR_TAB ++ AS2 (out,__SP_H__,%B1)); + } + else + { @@ -454,7 +291,7 @@ Index: gcc/config/avr/predicates.md } else if (test_hard_reg_class (STACK_REG, src)) { -@@ -1885,7 +2005,7 @@ +@@ -1885,7 +2030,7 @@ if (CONSTANT_ADDRESS_P (x)) { @@ -463,7 +300,7 @@ Index: gcc/config/avr/predicates.md { *l = 1; return AS2 (in,%0,__SREG__); -@@ -1893,7 +2013,8 @@ +@@ -1893,7 +2038,8 @@ if (avr_io_address_p (x, 1)) { *l = 1; @@ -473,7 +310,7 @@ Index: gcc/config/avr/predicates.md } *l = 2; return AS2 (lds,%0,%1); -@@ -2081,8 +2202,9 @@ +@@ -2081,8 +2227,9 @@ if (avr_io_address_p (base, 2)) { *l = 2; @@ -485,7 +322,7 @@ Index: gcc/config/avr/predicates.md } *l = 4; return (AS2 (lds,%A0,%A1) CR_TAB -@@ -2573,7 +2695,7 @@ +@@ -2573,7 +2720,7 @@ if (CONSTANT_ADDRESS_P (x)) { @@ -494,7 +331,7 @@ Index: gcc/config/avr/predicates.md { *l = 1; return AS2 (out,__SREG__,%1); -@@ -2581,7 +2703,8 @@ +@@ -2581,7 +2728,8 @@ if (avr_io_address_p (x, 1)) { *l = 1; @@ -504,7 +341,7 @@ Index: gcc/config/avr/predicates.md } *l = 2; return AS2 (sts,%0,%1); -@@ -2660,11 +2783,20 @@ +@@ -2660,11 +2808,20 @@ if (avr_io_address_p (base, 2)) { *l = 2; @@ -512,8 +349,8 @@ Index: gcc/config/avr/predicates.md - AS2 (out,%A0-0x20,%A1)); + op[2] = GEN_INT(AVR_IO_OFFSET); + if (AVR_XMEGA) -+ return (AS2 (out,%A0-%2,%B1) CR_TAB -+ AS2 (out,%B0-%2,%A1)); ++ return (AS2 (out,%A0-%2,%A1) CR_TAB ++ AS2 (out,%B0-%2,%B1)); + else + return (AS2 (out,%B0-%2,%B1) CR_TAB + AS2 (out,%A0-%2,%A1)); @@ -529,7 +366,7 @@ Index: gcc/config/avr/predicates.md } if (reg_base > 0) { -@@ -2679,11 +2811,20 @@ +@@ -2679,11 +2836,20 @@ AS2 (adiw,r26,1) CR_TAB AS2 (st,X,__tmp_reg__)); else @@ -555,7 +392,7 @@ Index: gcc/config/avr/predicates.md } else { -@@ -2691,14 +2832,27 @@ +@@ -2691,14 +2857,27 @@ return *l=2, (AS2 (st,X+,%A1) CR_TAB AS2 (st,X,%B1)); else @@ -588,7 +425,7 @@ Index: gcc/config/avr/predicates.md } else if (GET_CODE (base) == PLUS) { -@@ -2709,48 +2863,104 @@ +@@ -2709,48 +2888,104 @@ if (reg_base != REG_Y) fatal_insn ("incorrect insn:",insn); @@ -722,7 +559,7 @@ Index: gcc/config/avr/predicates.md { if (REGNO (XEXP (base, 0)) == REG_X) { -@@ -2771,7 +2981,7 @@ +@@ -2771,7 +3006,7 @@ *l = 2; return (AS2 (st,%0,%A1) CR_TAB @@ -731,7 +568,7 @@ Index: gcc/config/avr/predicates.md } fatal_insn ("unknown move insn:",insn); return ""; -@@ -4651,6 +4861,7 @@ +@@ -4651,6 +4886,7 @@ { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute }, { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute }, { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute }, @@ -739,7 +576,7 @@ Index: gcc/config/avr/predicates.md { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute }, { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute }, { NULL, 0, 0, false, false, false, NULL } -@@ -4739,6 +4950,14 @@ +@@ -4739,6 +4975,14 @@ func_name); } } @@ -754,7 +591,7 @@ Index: gcc/config/avr/predicates.md } return NULL_TREE; -@@ -4864,7 +5083,8 @@ +@@ -4864,7 +5108,8 @@ /* fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);*/ fputs ("__SREG__ = 0x3f\n" "__SP_H__ = 0x3e\n" @@ -764,7 +601,7 @@ Index: gcc/config/avr/predicates.md fputs ("__tmp_reg__ = 0\n" "__zero_reg__ = 1\n", asm_out_file); -@@ -5754,15 +5974,18 @@ +@@ -5754,15 +5999,18 @@ return !(regno & 1); } @@ -788,7 +625,7 @@ Index: gcc/config/avr/predicates.md } const char * -@@ -5940,16 +6163,17 @@ +@@ -5940,16 +6188,17 @@ if (GET_CODE (operands[1]) == CONST_INT) { @@ -810,3 +647,202 @@ Index: gcc/config/avr/predicates.md if (comp == EQ) output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands); else +diff -ur ../gcc-4.3.2.orig/gcc/config/avr/avr.h ./gcc/config/avr/avr.h +--- ../gcc-4.3.2.orig/gcc/config/avr/avr.h 2009-08-11 14:17:06.000000000 +0200 ++++ ./gcc/config/avr/avr.h 2009-08-11 14:40:01.000000000 +0200 +@@ -44,8 +44,11 @@ + /* Core have 'EICALL' and 'EIJMP' instructions. */ + int have_eijmp_eicall; + +- /* Reserved. */ +- int reserved; ++ /* Core is in Xmega family. */ ++ int xmega; ++ ++ /* Core have RAMPX, RAMPY and RAMPD registers. */ ++ int have_rampx_y_d; + + const char *const macro; + }; +@@ -68,6 +71,13 @@ + builtin_define ("__AVR_HAVE_ELPMX__"); \ + if (avr_have_movw_lpmx_p) \ + builtin_define ("__AVR_HAVE_MOVW__"); \ ++ if (avr_current_arch->have_elpm) \ ++ { \ ++ builtin_define ("__AVR_HAVE_RAMPZ__");\ ++ builtin_define ("__AVR_HAVE_ELPM__"); \ ++ } \ ++ if (avr_current_arch->have_elpmx) \ ++ builtin_define ("__AVR_HAVE_ELPMX__"); \ + if (avr_have_movw_lpmx_p) \ + builtin_define ("__AVR_HAVE_LPMX__"); \ + if (avr_asm_only_p) \ +@@ -88,6 +98,17 @@ + builtin_define ("__AVR_HAVE_EIJMP_EICALL__"); \ + if (TARGET_NO_INTERRUPTS) \ + builtin_define ("__NO_INTERRUPTS__"); \ ++ if (avr_current_arch->xmega) \ ++ { \ ++ builtin_define ("__AVR_XMEGA__"); \ ++ builtin_define ("__AVR_HAVE_SPMX__"); \ ++ } \ ++ if (avr_current_arch->have_rampx_y_d) \ ++ { \ ++ builtin_define ("__AVR_HAVE_RAMPX__");\ ++ builtin_define ("__AVR_HAVE_RAMPY__");\ ++ builtin_define ("__AVR_HAVE_RAMPD__");\ ++ } \ + } \ + while (0) + +@@ -107,10 +128,19 @@ + #define AVR_HAVE_LPMX (avr_have_movw_lpmx_p) + #define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm) + #define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall) ++#define AVR_XMEGA (avr_current_arch->xmega) ++#define AVR_HAVE_RAMPX_Y_D (avr_current_arch->have_rampx_y_d) + + #define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL) + #define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL) + ++#define AVR_IO_OFFSET (AVR_XMEGA ? 0 : 0x20) ++#define AVR_RAMPD_ADDR (AVR_XMEGA ? 0x38 : 0) ++#define AVR_RAMPX_ADDR (AVR_XMEGA ? 0x39 : 0) ++#define AVR_RAMPY_ADDR (AVR_XMEGA ? 0x3A : 0) ++#define AVR_RAMPZ_ADDR (AVR_XMEGA ? 0x3B : 0x5B) ++#define AVR_SREG_ADDR (AVR_XMEGA ? 0x3F: 0x5F) ++ + #define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)"); + + #define OVERRIDE_OPTIONS avr_override_options () +@@ -848,6 +878,12 @@ + mmcu=m3000*|\ + mmcu=m3001*: -m avr5}\ + %{mmcu=atmega256*:-m avr6}\ ++%{mmcu=atxmega32a4:-m avrxmega3} \ ++%{mmcu=atxmega64a3:-m avrxmega4} \ ++%{mmcu=atxmega64a1:-m avrxmega5} \ ++%{mmcu=atxmega128a3| \ ++ mmcu=atxmega256a3*:-m avrxmega6} \ ++%{mmcu=atxmega128a1:-m avrxmega7} \ + %{mmcu=atmega324*|\ + mmcu=atmega325*|\ + mmcu=atmega328p|\ +@@ -1024,7 +1060,15 @@ + %{mmcu=m3000s:crtm3000s.o%s} \ + %{mmcu=m3001b:crtm3001b.o%s} \ + %{mmcu=atmega2560|mmcu=avr6:crtm2560.o%s} \ +-%{mmcu=atmega2561:crtm2561.o%s}" ++%{mmcu=atmega2561:crtm2561.o%s} \ ++%{mmcu=atxmega3|mmcu=atxmega32a4:crtx32a4.o%s} \ ++%{mmcu=atxmega4|mmcu=atxmega64a3:crtx64a3.o%s} \ ++%{mmcu=atxmega5|mmcu=atxmega64a1:crtx64a1.o%s} \ ++%{mmcu=atxmega6|mmcu=atxmega128a3:crtx128a3.o%s} \ ++%{mmcu=atxmega256a3:crtx256a3.o%s} \ ++%{mmcu=atxmega256a3b:crtx256a3b.o%s} \ ++%{mmcu=atxmega7|mmcu=atxmega128a1:crtx128a1.o%s}" ++ + + #define EXTRA_SPECS {"crt_binutils", CRT_BINUTILS_SPECS}, + +@@ -1086,8 +1130,12 @@ + /* 'true' - if current function is a signal function + as specified by the "signal" attribute. */ + int is_signal; +- ++ + /* 'true' - if current function is a signal function ++ as specified by the "nmi" attribute. */ ++ int is_nmi; ++ ++ /* 'true' - if current function is a task function + as specified by the "OS_task" attribute. */ + int is_OS_task; + }; +diff -ur ../gcc-4.3.2.orig/gcc/config/avr/avr.md ./gcc/config/avr/avr.md +--- ../gcc-4.3.2.orig/gcc/config/avr/avr.md 2009-08-11 14:16:22.000000000 +0200 ++++ ./gcc/config/avr/avr.md 2009-08-11 14:34:10.000000000 +0200 +@@ -47,9 +47,6 @@ + (TMP_REGNO 0) ; temporary register r0 + (ZERO_REGNO 1) ; zero register r1 + +- (SREG_ADDR 0x5F) +- (RAMPZ_ADDR 0x5B) +- + (UNSPEC_STRLEN 0) + (UNSPEC_INDEX_JMP 1) + (UNSPEC_SEI 2) +@@ -2669,7 +2666,8 @@ + "(optimize > 0)" + { + operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff)); +- return AS2 (cbi,%0-0x20,%2); ++ operands[3] = GEN_INT(AVR_IO_OFFSET); ++ return AS2 (cbi,%0-%3,%2); + } + [(set_attr "length" "1") + (set_attr "cc" "none")]) +@@ -2681,7 +2679,8 @@ + "(optimize > 0)" + { + operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff)); +- return AS2 (sbi,%0-0x20,%2); ++ operands[3] = GEN_INT(AVR_IO_OFFSET); ++ return AS2 (sbi,%0-%3,%2); + } + [(set_attr "length" "1") + (set_attr "cc" "none")]) +diff -ur ../gcc-4.3.2.orig/gcc/config/avr/predicates.md ./gcc/config/avr/predicates.md +--- ../gcc-4.3.2.orig/gcc/config/avr/predicates.md 2007-08-02 12:49:31.000000000 +0200 ++++ ./gcc/config/avr/predicates.md 2009-08-11 14:34:10.000000000 +0200 +@@ -45,12 +45,16 @@ + ;; Return true if OP is a valid address for lower half of I/O space. + (define_predicate "low_io_address_operand" + (and (match_code "const_int") +- (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)"))) ++ (if_then_else (match_test "AVR_XMEGA") ++ (match_test "IN_RANGE((INTVAL (op)), 0x00, 0x1F)") ++ (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)")))) + + ;; Return true if OP is a valid address for high half of I/O space. + (define_predicate "high_io_address_operand" + (and (match_code "const_int") +- (match_test "IN_RANGE((INTVAL (op)), 0x40, 0x5F)"))) ++ (if_then_else (match_test "AVR_XMEGA") ++ (match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)") ++ (match_test "IN_RANGE((INTVAL (op)), 0x40, 0x5F)")))) + + ;; Return 1 if OP is the zero constant for MODE. + (define_predicate "const0_operand" +diff -ur ../gcc-4.3.2.orig/gcc/config/avr/t-avr ./gcc/config/avr/t-avr +--- ../gcc-4.3.2.orig/gcc/config/avr/t-avr 2009-08-11 14:17:06.000000000 +0200 ++++ ./gcc/config/avr/t-avr 2009-08-11 14:39:16.000000000 +0200 +@@ -37,8 +37,8 @@ + + FPBIT = fp-bit.c + +-MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6 +-MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 ++MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega3/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7 ++MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 + + # The many avr2 matches are not listed here - this is the default. + MULTILIB_MATCHES = \ +@@ -143,7 +143,15 @@ + mmcu?avr51=mmcu?m3000s \ + mmcu?avr51=mmcu?m3001b \ + mmcu?avr6=mmcu?atmega2560 \ +- mmcu?avr6=mmcu?atmega2561 ++ mmcu?avr6=mmcu?atmega2561 \ ++ mmcu?avrxmega3=mmcu?atxmega32a4 \ ++ mmcu?avrxmega4=mmcu?atxmega64a3 \ ++ mmcu?avrxmega5=mmcu?atxmega64a1 \ ++ mmcu?avrxmega6=mmcu?atxmega128a3 \ ++ mmcu?avrxmega6=mmcu?atxmega256a3 \ ++ mmcu?avrxmega6=mmcu?atxmega256a3b \ ++ mmcu?avrxmega7=mmcu?atxmega128a1 ++ + + MULTILIB_EXCEPTIONS = +