diff options
Diffstat (limited to 'patches/gcc-4.4.3/atmel/0004-Add-support-for-XMEGA-devices.patch')
-rw-r--r-- | patches/gcc-4.4.3/atmel/0004-Add-support-for-XMEGA-devices.patch | 897 |
1 files changed, 0 insertions, 897 deletions
diff --git a/patches/gcc-4.4.3/atmel/0004-Add-support-for-XMEGA-devices.patch b/patches/gcc-4.4.3/atmel/0004-Add-support-for-XMEGA-devices.patch deleted file mode 100644 index e76b8b7..0000000 --- a/patches/gcc-4.4.3/atmel/0004-Add-support-for-XMEGA-devices.patch +++ /dev/null @@ -1,897 +0,0 @@ -From 3c28f783fe1d9b707c3a07f5f3bc29db0e7e0ddf Mon Sep 17 00:00:00 2001 -From: Stephan Linz <linz@li-pro.net> -Date: Tue, 19 Apr 2011 23:30:06 +0200 -Subject: [PATCH 04/10] Add support for XMEGA devices - -Add support for the AVR XMEGA family of devices, device names that -are used in this family. This is the patch that will NOT be the -final XMEGA patch for the upcoming release. There are other -outstanding issues (raised on the mailing lists recently) with the -xmega support that I hope to address in the next day or two. - -Eric Weddington -Quote by Eric Weddington (2010-06-08): -http://www.mail-archive.com/avr-libc-dev@nongnu.org/msg04097.html - -Original ATMEL patch from: -http://distribute.atmel.no/tools/opensource/avr-gcc/gcc-4.4.3/51-gcc-4.4.3-xmega-v14.patch - -Signed-off-by: Stephan Linz <linz@li-pro.net> ---- - gcc/config/avr/avr.c | 339 +++++++++++++++++++++++++++++++++++++----- - gcc/config/avr/avr.h | 62 ++++++++- - gcc/config/avr/avr.md | 9 +- - gcc/config/avr/libgcc.S | 15 ++ - gcc/config/avr/predicates.md | 12 +- - gcc/config/avr/t-avr | 23 +++- - 6 files changed, 408 insertions(+), 52 deletions(-) - -diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c -index a8aff30..60918ac 100644 ---- a/gcc/config/avr/avr.c -+++ b/gcc/config/avr/avr.c -@@ -52,6 +52,7 @@ - static int avr_naked_function_p (tree); - static int interrupt_function_p (tree); - static int signal_function_p (tree); -+static int nmi_function_p (tree); - static int avr_OS_task_function_p (tree); - static int avr_OS_main_function_p (tree); - static int avr_regs_to_save (HARD_REG_SET *); -@@ -118,17 +119,24 @@ const struct base_arch_s *avr_current_arch; - section *progmem_section; - - static const struct base_arch_s avr_arch_types[] = { -- { 1, 0, 0, 0, 0, 0, 0, 0, NULL }, /* unknown device specified */ -- { 1, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=1" }, -- { 0, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=2" }, -- { 0, 0, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=25" }, -- { 0, 0, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=3" }, -- { 0, 0, 1, 0, 1, 0, 0, 0, "__AVR_ARCH__=31" }, -- { 0, 0, 1, 1, 0, 0, 0, 0, "__AVR_ARCH__=35" }, -- { 0, 1, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=4" }, -- { 0, 1, 1, 1, 0, 0, 0, 0, "__AVR_ARCH__=5" }, -- { 0, 1, 1, 1, 1, 1, 0, 0, "__AVR_ARCH__=51" }, -- { 0, 1, 1, 1, 1, 1, 1, 0, "__AVR_ARCH__=6" } -+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, NULL }, /* Unknown device specified. */ -+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=1" }, -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=2" }, -+ { 0, 0, 0, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=25" }, -+ { 0, 0, 1, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=3" }, -+ { 0, 0, 1, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=31" }, -+ { 0, 0, 1, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=35" }, -+ { 0, 1, 0, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=4" }, -+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=5" }, -+ { 0, 1, 1, 1, 1, 1, 0, 0, 0, "__AVR_ARCH__=51" }, -+ { 0, 1, 1, 1, 1, 1, 1, 0, 0, "__AVR_ARCH__=6" }, -+ { 0, 1, 0, 1, 0, 0, 0, 1, 0, "__AVR_ARCH__=101" }, -+ { 0, 1, 1, 1, 0, 0, 0, 1, 0, "__AVR_ARCH__=102" }, -+ { 0, 1, 1, 1, 0, 0, 0, 1, 1, "__AVR_ARCH__=103" }, -+ { 0, 1, 1, 1, 1, 1, 0, 1, 0, "__AVR_ARCH__=104" }, -+ { 0, 1, 1, 1, 1, 1, 0, 1, 1, "__AVR_ARCH__=105" }, -+ { 0, 1, 1, 1, 1, 1, 1, 1, 0, "__AVR_ARCH__=106" }, -+ { 0, 1, 1, 1, 1, 1, 1, 1, 1, "__AVR_ARCH__=107" } - }; - - /* These names are used as the index into the avr_arch_types[] table -@@ -146,7 +154,14 @@ enum avr_arch - ARCH_AVR4, - ARCH_AVR5, - ARCH_AVR51, -- ARCH_AVR6 -+ ARCH_AVR6, -+ ARCH_AVRXMEGA1, -+ ARCH_AVRXMEGA2, -+ ARCH_AVRXMEGA3, -+ ARCH_AVRXMEGA4, -+ ARCH_AVRXMEGA5, -+ ARCH_AVRXMEGA6, -+ ARCH_AVRXMEGA7 - }; - - struct mcu_type_s { -@@ -304,6 +319,35 @@ static const struct mcu_type_s avr_mcu_types[] = { - { "avr6", ARCH_AVR6, NULL }, - { "atmega2560", ARCH_AVR6, "__AVR_ATmega2560__" }, - { "atmega2561", ARCH_AVR6, "__AVR_ATmega2561__" }, -+ /* Enhanced, == 256K. */ -+ /* Xmega, <= 8K FLASH. */ -+ /* Xmega, > 8K, <= 64K FLASH, <= 64K RAM. */ -+ { "avrxmega2", ARCH_AVRXMEGA2, NULL }, -+ { "atxmega16a4", ARCH_AVRXMEGA2, "__AVR_ATxmega16A4__" }, -+ { "atxmega16d4", ARCH_AVRXMEGA2, "__AVR_ATxmega16D4__" }, -+ { "atxmega32a4", ARCH_AVRXMEGA2, "__AVR_ATxmega32A4__" }, -+ { "atxmega32d4", ARCH_AVRXMEGA2, "__AVR_ATxmega32D4__" }, -+ /* Xmega, > 8K, <= 64K FLASH, > 64K RAM. */ -+ /* { "avrxmega3", ARCH_AVRXMEGA3, NULL }, */ -+ /* Xmega, > 64K, <= 128K FLASH, <= 64K RAM. */ -+ { "avrxmega4", ARCH_AVRXMEGA4, NULL }, -+ { "atxmega64a3", ARCH_AVRXMEGA4, "__AVR_ATxmega64A3__" }, -+ { "atxmega64d3", ARCH_AVRXMEGA4, "__AVR_ATxmega64D3__" }, -+ /* Xmega, > 64K, <= 128K FLASH, > 64K RAM. */ -+ { "avrxmega5", ARCH_AVRXMEGA5, NULL }, -+ { "atxmega64a1", ARCH_AVRXMEGA5, "__AVR_ATxmega64A1__" }, -+ /* Xmega, > 128K, <= 256K FLASH, <= 64K RAM. */ -+ { "avrxmega6", ARCH_AVRXMEGA6, NULL }, -+ { "atxmega128a3", ARCH_AVRXMEGA6, "__AVR_ATxmega128A3__" }, -+ { "atxmega128d3", ARCH_AVRXMEGA6, "__AVR_ATxmega128D3__" }, -+ { "atxmega192a3", ARCH_AVRXMEGA6, "__AVR_ATxmega192A3__" }, -+ { "atxmega192d3", ARCH_AVRXMEGA6, "__AVR_ATxmega192D3__" }, -+ { "atxmega256a3", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3__" }, -+ { "atxmega256a3b",ARCH_AVRXMEGA6, "__AVR_ATxmega256A3B__" }, -+ { "atxmega256d3", ARCH_AVRXMEGA6, "__AVR_ATxmega256D3__" }, -+ /* Xmega, > 128K, <= 256K FLASH, > 64K RAM. */ -+ { "avrxmega7", ARCH_AVRXMEGA7, NULL }, -+ { "atxmega128a1", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1__" }, - /* Assembler only. */ - { "avr1", ARCH_AVR1, NULL }, - { "at90s1200", ARCH_AVR1, "__AVR_AT90S1200__" }, -@@ -505,6 +549,21 @@ signal_function_p (tree func) - return a != NULL_TREE; - } - -+/* Return nonzero if FUNC is a nmi function as specified -+ by the "nmi" attribute. */ -+ -+static int -+nmi_function_p (tree func) -+{ -+ tree a; -+ -+ if (TREE_CODE (func) != FUNCTION_DECL) -+ return 0; -+ -+ a = lookup_attribute ("nmi", DECL_ATTRIBUTES (func)); -+ return a != NULL_TREE; -+} -+ - /* Return nonzero if FUNC is a OS_task function. */ - - static int -@@ -703,6 +762,7 @@ expand_prologue (void) - 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); -+ cfun->machine->is_nmi = nmi_function_p (current_function_decl); - cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl); - cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl); - -@@ -740,17 +800,48 @@ expand_prologue (void) - - /* Push SREG. */ - insn = emit_move_insn (tmp_reg_rtx, -- gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR))); -+ gen_rtx_MEM (QImode, GEN_INT (AVR_SREG_ADDR))); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ insn = emit_move_insn (pushbyte, tmp_reg_rtx); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ -+ /* Push RAMPD, RAMPX, RAMPY. */ -+ if (AVR_HAVE_RAMPX_Y_D) -+ { -+ /* Push RAMPD. */ -+ insn = emit_move_insn (tmp_reg_rtx, -+ gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPD_ADDR))); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ insn = emit_move_insn (pushbyte, tmp_reg_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)) -+ { -+ insn = emit_move_insn (tmp_reg_rtx, -+ gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPX_ADDR))); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ insn = emit_move_insn (pushbyte, tmp_reg_rtx); -+ RTX_FRAME_RELATED_P (insn) = 1; -+ } -+ -+ /* Push RAMPY. */ -+ if (TEST_HARD_REG_BIT (set, REG_Y) && TEST_HARD_REG_BIT (set, REG_Y + 1)) -+ { -+ insn = emit_move_insn (tmp_reg_rtx, -+ gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPY_ADDR))); - RTX_FRAME_RELATED_P (insn) = 1; - insn = emit_move_insn (pushbyte, tmp_reg_rtx); - RTX_FRAME_RELATED_P (insn) = 1; -+ } -+ } - - /* Push RAMPZ. */ - if(AVR_HAVE_RAMPZ - && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1))) - { - insn = emit_move_insn (tmp_reg_rtx, -- gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR))); -+ gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPZ_ADDR))); - RTX_FRAME_RELATED_P (insn) = 1; - insn = emit_move_insn (pushbyte, tmp_reg_rtx); - RTX_FRAME_RELATED_P (insn) = 1; -@@ -762,6 +853,41 @@ expand_prologue (void) - - /* Prevent any attempt to delete the setting of ZERO_REG! */ - emit_use (zero_reg_rtx); -+ -+ -+ /* -+ Clear RAMP? registers if used for data access in the interrupt/signal -+ context. Do this after the zero register has been explictly cleared. -+ */ -+ if (AVR_HAVE_RAMPX_Y_D) -+ { -+ /* 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; -+ -+ if (TEST_HARD_REG_BIT (set, REG_X) && TEST_HARD_REG_BIT (set, REG_X + 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; -+ } -+ -+ if (TEST_HARD_REG_BIT (set, REG_Y) && TEST_HARD_REG_BIT (set, REG_Y + 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; -+ } -+ -+ if(AVR_HAVE_RAMPZ -+ && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1))) -+ { -+ /* 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; -+ } -+ } -+ - } - if (minimize && (frame_pointer_needed - || (AVR_2_BYTE_PC && live_seq > 6) -@@ -850,16 +976,16 @@ expand_prologue (void) - insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } -- else if (TARGET_NO_INTERRUPTS -- || cfun->machine->is_signal -- || cfun->machine->is_OS_main) -+ else if ((!AVR_XMEGA && TARGET_NO_INTERRUPTS) -+ || (!AVR_XMEGA && cfun->machine->is_signal) -+ || (!AVR_XMEGA && cfun->machine->is_OS_main)) - { - insn = - emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, - frame_pointer_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - } -- else if (cfun->machine->is_interrupt) -+ else if (!AVR_XMEGA && cfun->machine->is_interrupt) - { - insn = emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, - frame_pointer_rtx)); -@@ -1024,13 +1150,13 @@ expand_epilogue (void) - { - emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); - } -- else if (TARGET_NO_INTERRUPTS -- || cfun->machine->is_signal) -+ else if ((!AVR_XMEGA && TARGET_NO_INTERRUPTS) -+ || (!AVR_XMEGA && cfun->machine->is_signal)) - { - emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, - frame_pointer_rtx)); - } -- else if (cfun->machine->is_interrupt) -+ else if (!AVR_XMEGA && cfun->machine->is_interrupt) - { - emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, - frame_pointer_rtx)); -@@ -1083,14 +1209,39 @@ expand_epilogue (void) - && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1))) - { - emit_insn (gen_popqi (tmp_reg_rtx)); -- emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(RAMPZ_ADDR)), -+ emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(AVR_RAMPZ_ADDR)), -+ tmp_reg_rtx); -+ } -+ -+ /* Restore RAMPY, RAMPX, RAMPD using tmp reg as scratch. */ -+ if (AVR_HAVE_RAMPX_Y_D) -+ { -+ /* Pop RAMPY. */ -+ if (TEST_HARD_REG_BIT (set, REG_Y) && TEST_HARD_REG_BIT (set, REG_Y + 1)) -+ { -+ emit_insn (gen_popqi (tmp_reg_rtx)); -+ emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPY_ADDR)), -+ tmp_reg_rtx); -+ } -+ -+ /* Pop RAMPX. */ -+ if (TEST_HARD_REG_BIT (set, REG_X) && TEST_HARD_REG_BIT (set, REG_X + 1)) -+ { -+ emit_insn (gen_popqi (tmp_reg_rtx)); -+ emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPX_ADDR)), -+ tmp_reg_rtx); -+ } -+ -+ /* Pop RAMPD. */ -+ emit_insn (gen_popqi (tmp_reg_rtx)); -+ emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (AVR_RAMPD_ADDR)), - tmp_reg_rtx); - } - - /* Restore SREG using tmp reg as scratch. */ - emit_insn (gen_popqi (tmp_reg_rtx)); - -- emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)), -+ emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(AVR_SREG_ADDR)), - tmp_reg_rtx); - - /* Restore tmp REG. */ -@@ -1856,9 +2007,17 @@ output_movhi (rtx insn, rtx operands[], int *l) - return *l = 1, AS2 (out,__SP_L__,%A1); - /* Use simple load of stack pointer if no interrupts are - used. */ -- else if (TARGET_NO_INTERRUPTS) -+ else if (!AVR_XMEGA && TARGET_NO_INTERRUPTS) - return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB - AS2 (out,__SP_L__,%A1)); -+ if(AVR_XMEGA) -+ { -+ *l = 2; -+ return (AS2 (out,__SP_L__,%A1) CR_TAB -+ AS2 (out,__SP_H__,%B1)); -+ } -+ else -+ { - *l = 5; - return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB - "cli" CR_TAB -@@ -1866,6 +2025,7 @@ output_movhi (rtx insn, rtx operands[], int *l) - AS2 (out,__SREG__,__tmp_reg__) CR_TAB - AS2 (out,__SP_L__,%A1)); - } -+ } - else if (test_hard_reg_class (STACK_REG, src)) - { - *l = 2; -@@ -1999,7 +2159,7 @@ out_movqi_r_mr (rtx insn, rtx op[], int *l) - - if (CONSTANT_ADDRESS_P (x)) - { -- if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR) -+ if (CONST_INT_P (x) && INTVAL (x) == AVR_SREG_ADDR) - { - *l = 1; - return AS2 (in,%0,__SREG__); -@@ -2007,7 +2167,8 @@ out_movqi_r_mr (rtx insn, rtx op[], int *l) - if (optimize > 0 && io_address_operand (x, QImode)) - { - *l = 1; -- return AS2 (in,%0,%1-0x20); -+ op[2] = GEN_INT(AVR_IO_OFFSET); -+ return AS2 (in,%0,%1-%2); - } - *l = 2; - return AS2 (lds,%0,%1); -@@ -2195,8 +2356,9 @@ out_movhi_r_mr (rtx insn, rtx op[], int *l) - if (optimize > 0 && io_address_operand (base, HImode)) - { - *l = 2; -- return (AS2 (in,%A0,%A1-0x20) CR_TAB -- AS2 (in,%B0,%B1-0x20)); -+ op[2] = GEN_INT(AVR_IO_OFFSET); -+ return (AS2 (in,%A0,%A1-%2) CR_TAB -+ AS2 (in,%B0,%B1-%2)); - } - *l = 4; - return (AS2 (lds,%A0,%A1) CR_TAB -@@ -2695,7 +2857,7 @@ out_movqi_mr_r (rtx insn, rtx op[], int *l) - - if (CONSTANT_ADDRESS_P (x)) - { -- if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR) -+ if (CONST_INT_P (x) && INTVAL (x) == AVR_SREG_ADDR) - { - *l = 1; - return AS2 (out,__SREG__,%1); -@@ -2703,7 +2865,8 @@ out_movqi_mr_r (rtx insn, rtx op[], int *l) - if (optimize > 0 && io_address_operand (x, QImode)) - { - *l = 1; -- return AS2 (out,%0-0x20,%1); -+ op[2] = GEN_INT(AVR_IO_OFFSET); -+ return AS2 (out,%0-%2,%1); - } - *l = 2; - return AS2 (sts,%0,%1); -@@ -2782,9 +2945,18 @@ out_movhi_mr_r (rtx insn, rtx op[], int *l) - if (optimize > 0 && io_address_operand (base, HImode)) - { - *l = 2; -- return (AS2 (out,%B0-0x20,%B1) CR_TAB -- AS2 (out,%A0-0x20,%A1)); -+ op[2] = GEN_INT(AVR_IO_OFFSET); -+ if (AVR_XMEGA) -+ 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)); - } -+ if (AVR_XMEGA) -+ return *l = 4, (AS2 (sts,%A0,%A1) CR_TAB -+ AS2 (sts,%B0,%B1)); -+ else - return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB - AS2 (sts,%A0,%A1)); - } -@@ -2801,11 +2973,20 @@ out_movhi_mr_r (rtx insn, rtx op[], int *l) - AS2 (adiw,r26,1) CR_TAB - AS2 (st,X,__tmp_reg__)); - else -+ { -+ if (!AVR_XMEGA) - return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB - AS2 (adiw,r26,1) CR_TAB - AS2 (st,X,__tmp_reg__) CR_TAB - AS2 (sbiw,r26,1) CR_TAB - AS2 (st,X,r26)); -+ else -+ return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB -+ AS2 (st,X,r26) CR_TAB -+ AS2 (adiw,r26,1) CR_TAB -+ AS2 (st,X,__tmp_reg__) CR_TAB -+ AS2 (sbiw,r26,1)); -+ } - } - else - { -@@ -2813,14 +2994,27 @@ out_movhi_mr_r (rtx insn, rtx op[], int *l) - return *l=2, (AS2 (st,X+,%A1) CR_TAB - AS2 (st,X,%B1)); - else -+ { -+ if (!AVR_XMEGA) - return *l=3, (AS2 (adiw,r26,1) CR_TAB - AS2 (st,X,%B1) CR_TAB - AS2 (st,-X,%A1)); -+ else -+ return *l=3, (AS2 (st,X+,%A1) CR_TAB -+ AS2 (st,X,%B1) CR_TAB -+ AS2 (sbiw,r26,1)); -+ } - } - } - else -+ { -+ if (!AVR_XMEGA) - return *l=2, (AS2 (std,%0+1,%B1) CR_TAB - AS2 (st,%0,%A1)); -+ else -+ return *l=2, (AS2 (st,%0,%A1) CR_TAB -+ AS2 (std,%0+1,%B1)); -+ } - } - else if (GET_CODE (base) == PLUS) - { -@@ -2831,6 +3025,8 @@ out_movhi_mr_r (rtx insn, rtx op[], int *l) - if (reg_base != REG_Y) - fatal_insn ("incorrect insn:",insn); - -+ if (!AVR_XMEGA) -+ { - if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) - return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB - AS2 (std,Y+63,%B1) CR_TAB -@@ -2844,11 +3040,29 @@ out_movhi_mr_r (rtx insn, rtx op[], int *l) - AS2 (subi,r28,lo8(%o0)) CR_TAB - AS2 (sbci,r29,hi8(%o0))); - } -+ else -+ { -+ if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) -+ return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB -+ AS2 (std,Y+62,%A1) CR_TAB -+ AS2 (std,Y+63,%B1) CR_TAB -+ AS2 (sbiw,r28,%o0-62)); -+ -+ return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB -+ AS2 (sbci,r29,hi8(-%o0)) CR_TAB -+ AS2 (st,Y,%A1) CR_TAB -+ AS2 (std,Y+1,%B1) CR_TAB -+ AS2 (subi,r28,lo8(%o0)) CR_TAB -+ AS2 (sbci,r29,hi8(%o0))); -+ } -+ } - if (reg_base == REG_X) - { - /* (X + d) = R */ - if (reg_src == REG_X) - { -+ if (!AVR_XMEGA) -+ { - *l = 7; - return (AS2 (mov,__tmp_reg__,r26) CR_TAB - AS2 (mov,__zero_reg__,r27) CR_TAB -@@ -2858,21 +3072,57 @@ out_movhi_mr_r (rtx insn, rtx op[], int *l) - AS1 (clr,__zero_reg__) CR_TAB - AS2 (sbiw,r26,%o0)); - } -+ else -+ { -+ *l = 7; -+ return (AS2 (mov,__tmp_reg__,r26) CR_TAB -+ AS2 (mov,__zero_reg__,r27) CR_TAB -+ AS2 (adiw,r26,%o0) CR_TAB -+ AS2 (st,X+,__tmp_reg__) CR_TAB -+ AS2 (st,X,__zero_reg__) CR_TAB -+ AS1 (clr,__zero_reg__) CR_TAB -+ AS2 (sbiw,r26,%o0+1)); -+ } -+ } -+ if (!AVR_XMEGA) -+ { - *l = 4; - return (AS2 (adiw,r26,%o0+1) CR_TAB - AS2 (st,X,%B1) CR_TAB - AS2 (st,-X,%A1) CR_TAB - AS2 (sbiw,r26,%o0)); - } -+ else -+ { -+ *l = 4; -+ return (AS2 (adiw,r26,%o0) CR_TAB -+ AS2 (st,X+,%A1) CR_TAB -+ AS2 (st,X,%B1) CR_TAB -+ AS2 (sbiw,r26,%o0+1)); -+ } -+ } -+ -+ if (!AVR_XMEGA) - return *l=2, (AS2 (std,%B0,%B1) CR_TAB - AS2 (std,%A0,%A1)); -+ else -+ return *l=2, (AS2 (std,%A0,%A1) CR_TAB -+ AS2 (std,%B0,%B1)); - } - else if (GET_CODE (base) == PRE_DEC) /* (--R) */ -+ { -+ if (mem_volatile_p && AVR_XMEGA) -+ return *l = 4, (AS2 (sbiw,%r0,2) CR_TAB -+ AS2 (st,%p0+,%A1) CR_TAB -+ AS2 (st,%p0,%B1) CR_TAB -+ AS2 (sbiw,%r0,1)); -+ else - return *l=2, (AS2 (st,%0,%B1) CR_TAB - AS2 (st,%0,%A1)); -+ } - else if (GET_CODE (base) == POST_INC) /* (R++) */ - { -- if (mem_volatile_p) -+ if (mem_volatile_p && !AVR_XMEGA) - { - if (REGNO (XEXP (base, 0)) == REG_X) - { -@@ -4872,6 +5122,16 @@ avr_asm_declare_function_name (FILE *file, const char *name, tree decl) - } - } - -+ else if (cfun->machine->is_nmi) -+ { -+ if (strncmp (name, "__vector", strlen ("__vector")) != 0) -+ { -+ warning_at (DECL_SOURCE_LOCATION (decl), 0, -+ "%qs appears to be a misspelled nmi handler", -+ name); -+ } -+ } -+ - ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); - ASM_OUTPUT_LABEL (file, name); - } -@@ -4996,6 +5256,7 @@ const struct attribute_spec avr_attribute_table[] = - { "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 }, -+ { "nmi", 0, 0, true, false, false, avr_handle_fndecl_attribute }, - { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute }, - { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute }, - { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute }, -@@ -5253,7 +5514,8 @@ avr_file_start (void) - /* fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);*/ - fputs ("__SREG__ = 0x3f\n" - "__SP_H__ = 0x3e\n" -- "__SP_L__ = 0x3d\n", asm_out_file); -+ "__SP_L__ = 0x3d\n" -+ "__CCP__ = 0x34\n", asm_out_file); - - fputs ("__tmp_reg__ = 0\n" - "__zero_reg__ = 1\n", asm_out_file); -@@ -6354,16 +6616,17 @@ avr_out_sbxx_branch (rtx insn, rtx operands[]) - - if (GET_CODE (operands[1]) == CONST_INT) - { -- if (INTVAL (operands[1]) < 0x40) -+ operands[4] = GEN_INT(AVR_IO_OFFSET); /* operands[3] is for the jump */ -+ if (low_io_address_operand (operands[1], VOIDmode)) - { - if (comp == EQ) -- output_asm_insn (AS2 (sbis,%1-0x20,%2), operands); -+ output_asm_insn (AS2 (sbis,%1-%4,%2), operands); - else -- output_asm_insn (AS2 (sbic,%1-0x20,%2), operands); -+ output_asm_insn (AS2 (sbic,%1-%4,%2), operands); - } - else - { -- output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands); -+ output_asm_insn (AS2 (in,__tmp_reg__,%1-%4), operands); - if (comp == EQ) - output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands); - else -diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h -index c0efa57..e580d5e 100644 ---- a/gcc/config/avr/avr.h -+++ b/gcc/config/avr/avr.h -@@ -44,8 +44,11 @@ struct base_arch_s { - /* 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; - }; -@@ -94,6 +97,17 @@ extern const struct base_arch_s *avr_current_arch; - } \ - 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) - -@@ -109,10 +123,19 @@ extern GTY(()) section *progmem_section; - #define AVR_HAVE_LPMX (avr_current_arch->have_movw_lpmx) - #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 () -@@ -853,6 +876,20 @@ mmcu=*:-mmcu=%*}" - mmcu=m3000*|\ - mmcu=m3001*: -m avr5}\ - %{mmcu=atmega256*:-m avr6}\ -+%{mmcu=atxmega16a4|\ -+ mmcu=atxmega16d4|\ -+ mmcu=atxmega32d4|\ -+ mmcu=atxmega32a4:-m avrxmega2} \ -+%{mmcu=atxmega64a3|\ -+ mmcu=atxmega64d3:-m avrxmega4} \ -+%{mmcu=atxmega64a1:-m avrxmega5} \ -+%{mmcu=atxmega128a3|\ -+ mmcu=atxmega128d3|\ -+ mmcu=atxmega192a3|\ -+ mmcu=atxmega192d3|\ -+ mmcu=atxmega256a3*|\ -+ mmcu=atxmega256d3:-m avrxmega6} \ -+%{mmcu=atxmega128a1:-m avrxmega7} \ - %{mmcu=atmega324*|\ - mmcu=atmega325*|\ - mmcu=atmega328p|\ -@@ -1042,7 +1079,22 @@ mmcu=*:-mmcu=%*}" - %{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=avrxmega2|mmcu=atxmega32d4:crtx32d4.o%s} \ -+%{mmcu=atxmega16a4:crtx16a4.o%s} \ -+%{mmcu=atxmega16d4:crtx16d4.o%s} \ -+%{mmcu=atxmega3|mmcu=atxmega32a4:crtx32a4.o%s} \ -+%{mmcu=atxmega4|mmcu=atxmega64a3:crtx64a3.o%s} \ -+%{mmcu=atxmega64d3:crtx64d3.o%s} \ -+%{mmcu=atxmega5|mmcu=atxmega64a1:crtx64a1.o%s} \ -+%{mmcu=atxmega6|mmcu=atxmega128a3:crtx128a3.o%s} \ -+%{mmcu=atxmega128d3:crtx128d3.o%s}\ -+%{mmcu=atxmega192a3:crtx192a3.o%s}\ -+%{mmcu=atxmega192d3:crtx192d3.o%s}\ -+%{mmcu=atxmega256a3:crtx256a3.o%s} \ -+%{mmcu=atxmega256a3b:crtx256a3b.o%s} \ -+%{mmcu=atxmega256d3:crtx256d3.o%s} \ -+%{mmcu=atxmega7|mmcu=atxmega128a1:crtx128a1.o%s}" - - #define EXTRA_SPECS {"crt_binutils", CRT_BINUTILS_SPECS}, - -@@ -1102,6 +1154,10 @@ struct machine_function GTY(()) - 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 --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md -index 5090e53..f91e98c 100644 ---- a/gcc/config/avr/avr.md -+++ b/gcc/config/avr/avr.md -@@ -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) -@@ -3017,7 +3014,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")]) -@@ -3029,7 +3027,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 --git a/gcc/config/avr/libgcc.S b/gcc/config/avr/libgcc.S -index 76fdd9f..5a711a8 100644 ---- a/gcc/config/avr/libgcc.S -+++ b/gcc/config/avr/libgcc.S -@@ -637,11 +637,19 @@ __prologue_saves__: - in r29,__SP_H__ - sub r28,r26 - sbc r29,r27 -+ -+/* Restore stack pointer. */ -+#if defined (__AVR_XMEGA__) -+ out __SP_L__,r28 -+ out __SP_H__,r29 -+#else - in __tmp_reg__,__SREG__ - cli - out __SP_H__,r29 - out __SREG__,__tmp_reg__ - out __SP_L__,r28 -+#endif -+ - #if defined (__AVR_HAVE_EIJMP_EICALL__) - eijmp - #else -@@ -679,11 +687,18 @@ __epilogue_restores__: - ldd r27,Y+1 - add r28,r30 - adc r29,__zero_reg__ -+ -+/* Restore stack pointer. */ -+#if defined(__AVR_XMEGA__) -+ out __SP_L__,r28 -+ out __SP_H__,r29 -+#else - in __tmp_reg__,__SREG__ - cli - out __SP_H__,r29 - out __SREG__,__tmp_reg__ - out __SP_L__,r28 -+#endif - mov_l r28, r26 - mov_h r29, r27 - ret -diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md -index 020fb5f..aca33d7 100755 ---- a/gcc/config/avr/predicates.md -+++ b/gcc/config/avr/predicates.md -@@ -45,17 +45,23 @@ - ;; 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 true if OP is a valid address of I/O space. - (define_predicate "io_address_operand" - (and (match_code "const_int") -- (match_test "IN_RANGE((INTVAL (op)), 0x20, (0x60 - GET_MODE_SIZE(mode)))"))) -+ (if_then_else (match_test "AVR_XMEGA") -+ (match_test "IN_RANGE((INTVAL (op)), 0x0, (0x40 - GET_MODE_SIZE(mode)))") -+ (match_test "IN_RANGE((INTVAL (op)), 0x20, (0x60 - GET_MODE_SIZE(mode)))")))) - - ;; Return 1 if OP is the zero constant for MODE. - (define_predicate "const0_operand" -diff --git a/gcc/config/avr/t-avr b/gcc/config/avr/t-avr -index ef6b7ae..d375daf 100644 ---- a/gcc/config/avr/t-avr -+++ b/gcc/config/avr/t-avr -@@ -73,8 +73,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c $(srcdir)/config/avr/t-avr - - 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=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7 -+MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 - - # The many avr2 matches are not listed here - this is the default. - MULTILIB_MATCHES = \ -@@ -186,7 +186,24 @@ MULTILIB_MATCHES = \ - mmcu?avr51=mmcu?m3000s \ - mmcu?avr51=mmcu?m3001b \ - mmcu?avr6=mmcu?atmega2560 \ -- mmcu?avr6=mmcu?atmega2561 -+ mmcu?avr6=mmcu?atmega2561 \ -+ mmcu?avr6=mmcu?atmega2560 \ -+ mmcu?avr6=mmcu?atmega2561 \ -+ mmcu?avrxmega2=mmcu?atxmega16a4 \ -+ mmcu?avrxmega2=mmcu?atxmega16d4 \ -+ mmcu?avrxmega2=mmcu?atxmega32d4 \ -+ mmcu?avrxmega2=mmcu?atxmega32a4 \ -+ mmcu?avrxmega4=mmcu?atxmega64a3 \ -+ mmcu?avrxmega4=mmcu?atxmega64d3 \ -+ mmcu?avrxmega5=mmcu?atxmega64a1 \ -+ mmcu?avrxmega6=mmcu?atxmega128a3 \ -+ mmcu?avrxmega6=mmcu?atxmega128d3 \ -+ mmcu?avrxmega6=mmcu?atxmega192a3 \ -+ mmcu?avrxmega6=mmcu?atxmega192d3 \ -+ mmcu?avrxmega6=mmcu?atxmega256a3 \ -+ mmcu?avrxmega6=mmcu?atxmega256a3b \ -+ mmcu?avrxmega6=mmcu?atxmega256d3 \ -+ mmcu?avrxmega7=mmcu?atxmega128a1 - - MULTILIB_EXCEPTIONS = - --- -1.6.0.4 - |