summaryrefslogtreecommitdiffstats
path: root/patches/gcc-4.4.3/atmel/0004-Add-support-for-XMEGA-devices.patch
diff options
context:
space:
mode:
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.patch897
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
-