[packages/crossavr-gcc] - updated to 4.7.3 (4.7.2 and older fail to compile with ICE) - updated Atmel official AVR8-GNU tool

baggins baggins at pld-linux.org
Wed Jun 12 13:27:14 CEST 2013


commit 64c2fd3a8074811ce245fd562fc09a19fb7baf51
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Wed Jun 12 13:25:47 2013 +0200

    - updated to 4.7.3 (4.7.2 and older fail to compile with ICE)
    - updated Atmel official AVR8-GNU toolchain version 3.4.2
    - disabled patches that cause assembler Internal error (aborting at symbols.c line 96 in symbol_new)

 000-gcc-PR50293.patch                              |   89 +
 200-gcc-libiberty-Makefile.in.patch                |   13 -
 300-gcc-fixedpoint-3-4-2010.patch                  | 2755 --------------------
 300-gcc-xmega-support.patch                        |  171 ++
 301-gcc-tiny-support.patch                         | 1970 ++++++++++++++
 301-gcc-xmega-v14.patch                            |  769 ------
 302-gcc-avrtiny10.patch                            | 2132 ---------------
 302-gcc-mlist-devices.patch                        |   59 +
 303-ata6289-architecture-correction.patch          |   38 +
 303-gcc-osmain.patch                               |   54 -
 304-gcc-builtins-v6.patch                          |  585 -----
 305-gcc-avrtiny10-non-fixedpoint.patch             |   49 -
 306-gcc-option-list-devices.patch                  |   50 -
 307-gcc-avrtc536.patch                             |   28 -
 308-gcc-avrtc537.patch                             |   31 -
 400-gcc-new-devices.patch                          |  127 -
 400-gcc-public-devices-support.patch               |  222 ++
 401-gcc-atmega32_5_50_90_pa.patch                  |   46 -
 401-gcc-non-public-devices-support.patch           |  110 +
 402-gcc-atmega64_128_2564RFR2.patch                |   27 +
 402-gcc-attiny1634.patch                           |   22 -
 403-gcc-atmega48pa.patch                           |   22 -
 403-gcc-atmxts200.patch                            |   11 +
 404-gcc-atxmega_16_32_a4u.patch                    |  114 -
 405-gcc-atxmega64_128_192_256a3u.patch             |   49 -
 406-gcc-atmegarfr2_a2.patch                        |   58 -
 407-gcc-atmega165pa.patch                          |   22 -
 408-gcc-atxmega384c3.patch                         |   33 -
 410-gcc-atxmega128a4u.patch                        |   22 -
 411-gcc-atxmega64d4.patch                          |   22 -
 412-gcc-atmega164pa_168pa_32a_64a.patch            |   68 -
 413-gcc-atxmega64_128_b3.patch                     |   38 -
 414-gcc-atxmega64b1.patch                          |   22 -
 415-gcc-atmega_8a_128a_1284.patch                  |   44 -
 416-gcc-atxmega64a4u.patch                         |   24 -
 417-gcc-atxmega128d4.patch                         |   22 -
 418-gcc-atmxt336s.patch                            |   22 -
 419-gcc-atxmega16c4_32c4_128c3_256c3.patch         |   60 -
 420-gcc-atxmega384d3.patch                         |   22 -
 421-gcc-atmega48hvf.patch                          |   22 -
 422-gcc-atmega26hvg.patch                          |   22 -
 423-gcc-atmxt224_224e.patch                        |   24 -
 424-gcc-atxmega192c3.patch                         |   22 -
 425-gcc-atmxt112sl.patch                           |   22 -
 426-gcc-atxmega64c3.patch                          |   22 -
 427-gcc-ata6285_6286.patch                         |   24 -
 428-gcc-attiny828.patch                            |   22 -
 429-gcc-ata5790_5790n_5795.patch                   |   26 -
 430-gcc-ata5272_ata5505.patch                      |   38 -
 431-gcc-atmxt540s.patch                            |   24 -
 432-gcc-ata5831.patch                              |   54 -
 433-gcc-attiny841.patch                            |   22 -
 434-gcc-atxmega32_16_8e5.patch                     |   26 -
 500-gcc-bug13473.patch                             |   14 -
 501-gcc-avrtc579.patch                             |  304 +++
 501-gcc-avrtiny10-bug-12510.patch                  |   43 -
 502-gcc-bug12915.patch                             |   14 -
 502-gcc-pr54796.patch                              |  139 +
 503-gcc-avrtc-513.patch                            |   63 +
 503-gcc-bug13789.patch                             |   40 -
 504-gcc-avrtc-610.patch                            |   13 +
 504-gcc-conditional-register.patch                 |   85 -
 505-gcc-avrtc381-tiny.patch                        |   47 -
 505-gcc-avrtc586.patch                             |   67 +
 506-gcc-avrtc541.patch                             |   42 -
 507-gcc-avrtc-518.patch                            |   23 -
 508-gcc-avrtc514-tiny.patch                        |   12 -
 509-gcc-AVRTC-544-call-used-registers-tiny10.patch |  173 --
 510-gcc-avrtc496-tiny.patch                        |   42 -
 511-gcc-avrtc539-backported.patch                  |   44 -
 512-gcc-avrtc542.patch                             | 2753 -------------------
 513-gcc-avrtc556-tiny-same-base-and-dest.patch     |  130 -
 514-gcc-avrtc558.patch                             |   46 -
 515-gcc-avrtc446.patch                             |   38 -
 crossavr-gcc.spec                                  |  153 +-
 gcc-bug51969.patch                                 |   18 -
 76 files changed, 3313 insertions(+), 11382 deletions(-)
---
diff --git a/crossavr-gcc.spec b/crossavr-gcc.spec
index 225aae2..68a3aab 100644
--- a/crossavr-gcc.spec
+++ b/crossavr-gcc.spec
@@ -9,79 +9,32 @@ Summary(pl.UTF-8):	Skrośne narzędzia programistyczne GNU dla AVR - gcc
 Summary(pt_BR.UTF-8):	Utilitários para desenvolvimento de binários da GNU - AVR gcc
 Summary(tr.UTF-8):	GNU geliştirme araçları - AVR gcc
 Name:		crossavr-gcc
-Version:	4.6.2
-Release:	6
+Version:	4.7.3
+Release:	1
 Epoch:		1
-Patch1:		gcc-bug51969.patch
-# Patches 1xx are taken form Atmel official AVR8-GNU toolchain version 3.4.1.830
-Patch100:	200-gcc-libiberty-Makefile.in.patch
-Patch101:	300-gcc-fixedpoint-3-4-2010.patch
-Patch102:	301-gcc-xmega-v14.patch
-Patch103:	302-gcc-avrtiny10.patch
-Patch104:	303-gcc-osmain.patch
-Patch105:	304-gcc-builtins-v6.patch
-Patch106:	305-gcc-avrtiny10-non-fixedpoint.patch
-Patch107:	306-gcc-option-list-devices.patch
-Patch108:	307-gcc-avrtc536.patch
-Patch109:	308-gcc-avrtc537.patch
-Patch110:	400-gcc-new-devices.patch
-Patch111:	401-gcc-atmega32_5_50_90_pa.patch
-Patch112:	402-gcc-attiny1634.patch
-Patch113:	403-gcc-atmega48pa.patch
-Patch114:	404-gcc-atxmega_16_32_a4u.patch
-Patch115:	405-gcc-atxmega64_128_192_256a3u.patch
-Patch116:	406-gcc-atmegarfr2_a2.patch
-Patch117:	407-gcc-atmega165pa.patch
-Patch118:	408-gcc-atxmega384c3.patch
-Patch119:	410-gcc-atxmega128a4u.patch
-Patch120:	411-gcc-atxmega64d4.patch
-Patch121:	412-gcc-atmega164pa_168pa_32a_64a.patch
-Patch122:	413-gcc-atxmega64_128_b3.patch
-Patch123:	414-gcc-atxmega64b1.patch
-Patch124:	415-gcc-atmega_8a_128a_1284.patch
-Patch125:	416-gcc-atxmega64a4u.patch
-Patch126:	417-gcc-atxmega128d4.patch
-Patch127:	418-gcc-atmxt336s.patch
-Patch128:	419-gcc-atxmega16c4_32c4_128c3_256c3.patch
-Patch129:	420-gcc-atxmega384d3.patch
-Patch130:	421-gcc-atmega48hvf.patch
-Patch131:	422-gcc-atmega26hvg.patch
-Patch132:	423-gcc-atmxt224_224e.patch
-Patch133:	424-gcc-atxmega192c3.patch
-Patch134:	425-gcc-atmxt112sl.patch
-Patch135:	426-gcc-atxmega64c3.patch
-Patch136:	427-gcc-ata6285_6286.patch
-Patch137:	428-gcc-attiny828.patch
-Patch138:	429-gcc-ata5790_5790n_5795.patch
-Patch139:	430-gcc-ata5272_ata5505.patch
-Patch140:	431-gcc-atmxt540s.patch
-Patch141:	432-gcc-ata5831.patch
-Patch142:	433-gcc-attiny841.patch
-Patch143:	434-gcc-atxmega32_16_8e5.patch
-Patch144:	500-gcc-bug13473.patch
-Patch145:	501-gcc-avrtiny10-bug-12510.patch
-Patch146:	502-gcc-bug12915.patch
-Patch147:	503-gcc-bug13789.patch
-Patch148:	504-gcc-conditional-register.patch
-Patch149:	505-gcc-avrtc381-tiny.patch
-Patch150:	506-gcc-avrtc541.patch
-Patch151:	507-gcc-avrtc-518.patch
-Patch152:	508-gcc-avrtc514-tiny.patch
-Patch153:	509-gcc-AVRTC-544-call-used-registers-tiny10.patch
-Patch154:	510-gcc-avrtc496-tiny.patch
-Patch155:	511-gcc-avrtc539-backported.patch
-Patch156:	512-gcc-avrtc542.patch
-Patch157:	513-gcc-avrtc556-tiny-same-base-and-dest.patch
-Patch158:	514-gcc-avrtc558.patch
-Patch159:	515-gcc-avrtc446.patch
+# Patches 1xx are taken form Atmel official AVR8-GNU toolchain version 3.4.2
+# http://distribute.atmel.no/tools/opensource/Atmel-AVR-Toolchain-3.4.2/avr/avr-patches.tar.gz
+Patch100:	300-gcc-xmega-support.patch
+Patch101:	301-gcc-tiny-support.patch
+Patch102:	302-gcc-mlist-devices.patch
+Patch103:	303-ata6289-architecture-correction.patch
+Patch104:	400-gcc-public-devices-support.patch
+Patch105:	401-gcc-non-public-devices-support.patch
+Patch106:	402-gcc-atmega64_128_2564RFR2.patch
+Patch107:	403-gcc-atmxts200.patch
+Patch108:	501-gcc-avrtc579.patch
+Patch109:	502-gcc-pr54796.patch
+Patch110:	503-gcc-avrtc-513.patch
+Patch111:	504-gcc-avrtc-610.patch
+Patch112:	505-gcc-avrtc586.patch
 License:	GPL
 Group:		Development/Languages
 Source0:	ftp://gcc.gnu.org/pub/gcc/releases/gcc-%{version}/gcc-%{version}.tar.bz2
-# Source0-md5:	028115c4fbfb6cfd75d6369f4a90d87e
+# Source0-md5:	86f428a30379bdee0224e353ee2f999e
 BuildRequires:	/bin/bash
 BuildRequires:	autoconf
 BuildRequires:	bison
-BuildRequires:	crossavr-binutils
+BuildRequires:	crossavr-binutils >= 2.23.1
 BuildRequires:	elfutils-devel >= 0.145-1
 BuildRequires:	flex
 BuildRequires:	gmp-devel >= 4.1
@@ -91,7 +44,7 @@ BuildRequires:	perl-tools-pod
 BuildRequires:	ppl-devel
 BuildRequires:	rpmbuild(macros) >= 1.565
 BuildRequires:	sed >= 4.0
-Requires:	crossavr-binutils >= 2.15.91.0.2
+Requires:	crossavr-binutils >= 2.23.1
 %{!?with_bootstrap:Requires:	crossavr-libc}
 Requires:	gcc-dirs
 BuildRoot:	%{tmpdir}/%{name}-%{version}-root-%(id -u -n)
@@ -133,67 +86,19 @@ Ten pakiet dodaje obsługę C++ do kompilatora gcc dla AVR.
 %prep
 %setup -q -n gcc-%{version}
 cd gcc/config/%{target} && %undos -f c,h && cd -
-%patch1 -p2
 %patch100 -p0
-%patch101 -p0
+#patch101 -p0
 %patch102 -p0
 %patch103 -p0
-%patch104 -p0
-%patch105 -p0
-%patch106 -p0
-%patch107 -p0
-%patch108 -p0
+#patch104 -p0
+#patch105 -p0
+#patch106 -p0
+#patch107 -p0
+#patch108 -p0
 %patch109 -p0
-%patch110 -p0
+#patch110 -p0
 %patch111 -p0
-%patch112 -p0
-%patch113 -p0
-%patch114 -p0
-%patch115 -p0
-%patch116 -p0
-%patch117 -p0
-%patch118 -p0
-%patch119 -p0
-%patch120 -p0
-%patch121 -p0
-%patch122 -p0
-%patch123 -p0
-%patch124 -p0
-%patch125 -p0
-%patch126 -p0
-%patch127 -p0
-%patch128 -p0
-%patch129 -p0
-%patch130 -p0
-%patch131 -p0
-%patch132 -p0
-%patch133 -p0
-%patch134 -p0
-%patch135 -p0
-%patch136 -p0
-%patch137 -p0
-%patch138 -p0
-%patch139 -p0
-%patch140 -p0
-%patch141 -p0
-%patch142 -p0
-%patch143 -p0
-%patch144 -p0
-%patch145 -p0
-%patch146 -p0
-%patch147 -p0
-%patch148 -p0
-%patch149 -p0
-%patch150 -p0
-%patch151 -p0
-%patch152 -p0
-%patch153 -p0
-%patch154 -p0
-%patch155 -p0
-%patch156 -p0
-%patch157 -p0
-%patch158 -p0
-%patch159 -p0
+#patch112 -p0
 
 %build
 rm -rf obj-%{target}
@@ -273,6 +178,8 @@ rm -rf $RPM_BUILD_ROOT
 %{gcclib}/libg*.a
 %{gcclib}/%{target}*
 %{gcclib}/plugin
+%dir %{gcclib}/tiny-stack
+%{gcclib}/tiny-stack/*.a
 %dir %{gcclib}/include
 %{gcclib}/include/*.h
 %{_mandir}/man1/%{target}-cpp.1*
diff --git a/000-gcc-PR50293.patch b/000-gcc-PR50293.patch
new file mode 100644
index 0000000..071f5c7
--- /dev/null
+++ b/000-gcc-PR50293.patch
@@ -0,0 +1,89 @@
+diff -Naurp gcc/gcc.c gcc/gcc.c
+--- gcc/gcc.c	2012-08-06 20:04:27.000000000 +0530
++++ gcc/gcc.c	2013-03-21 12:13:51.000000000 +0530
+@@ -267,6 +267,7 @@ static const char *compare_debug_dump_op
+ static const char *compare_debug_self_opt_spec_function (int, const char **);
+ static const char *compare_debug_auxbase_opt_spec_function (int, const char **);
+ static const char *pass_through_libs_spec_func (int, const char **);
++static char *convert_white_space (char *);
+ 

+ /* The Specs Language
+ 
+@@ -6475,6 +6476,7 @@ main (int argc, char **argv)
+ 				    X_OK, false);
+   if (lto_wrapper_file)
+     {
++      lto_wrapper_file = convert_white_space (lto_wrapper_file);
+       lto_wrapper_spec = lto_wrapper_file;
+       obstack_init (&collect_obstack);
+       obstack_grow (&collect_obstack, "COLLECT_LTO_WRAPPER=",
+@@ -6876,12 +6878,13 @@ warranty; not even for MERCHANTABILITY o
+ 			      + strlen (fuse_linker_plugin), 0))
+ #endif
+ 	    {
+-	      linker_plugin_file_spec = find_a_file (&exec_prefixes,
+-						     LTOPLUGINSONAME, R_OK,
+-						     false);
+-	      if (!linker_plugin_file_spec)
++	      char *temp_spec = find_a_file (&exec_prefixes,
++					     LTOPLUGINSONAME, R_OK,
++					     false);
++	      if (!temp_spec)
+ 		fatal_error ("-fuse-linker-plugin, but %s not found",
+ 			     LTOPLUGINSONAME);
++	      linker_plugin_file_spec = convert_white_space (temp_spec);
+ 	    }
+ #endif
+ 	  lto_gcc_spec = argv[0];
+@@ -8318,3 +8321,51 @@ pass_through_libs_spec_func (int argc, c
+     }
+   return prepended;
+ }
++
++/* Insert backslash before spaces in ORIG (usually a file path), to 
++   avoid being broken by spec parser.
++
++   This function is needed as do_spec_1 treats white space (' ' and '\t')
++   as the end of an argument. But in case of -plugin /usr/gcc install/xxx.so,
++   the file name should be treated as a single argument rather than being
++   broken into multiple. Solution is to insert '\\' before the space in a 
++   file name.
++   
++   This function converts and only converts all occurrence of ' ' 
++   to '\\' + ' ' and '\t' to '\\' + '\t'.  For example:
++   "a b"  -> "a\\ b"
++   "a  b" -> "a\\ \\ b"
++   "a\tb" -> "a\\\tb"
++   "a\\ b" -> "a\\\\ b"
++
++   orig: input null-terminating string that was allocated by xalloc. The
++   memory it points to might be freed in this function. Behavior undefined
++   if ORIG wasn't xalloced or was freed already at entry.
++
++   Return: ORIG if no conversion needed. Otherwise a newly allocated string
++   that was converted from ORIG.  */
++
++static char *
++convert_white_space (char *orig)
++{
++  int len, number_of_space = 0;
++
++  for (len = 0; orig[len]; len++)
++    if (orig[len] == ' ' || orig[len] == '\t') number_of_space++;
++
++  if (number_of_space)
++    {
++      char *new_spec = (char *) xmalloc (len + number_of_space + 1);
++      int j, k;
++      for (j = 0, k = 0; j <= len; j++, k++)
++	{
++	  if (orig[j] == ' ' || orig[j] == '\t')
++	    new_spec[k++] = '\\';
++	  new_spec[k] = orig[j];
++	}
++      free (orig);
++      return new_spec;
++  }
++  else
++    return orig;
++}
diff --git a/200-gcc-libiberty-Makefile.in.patch b/200-gcc-libiberty-Makefile.in.patch
deleted file mode 100644
index ff42fed..0000000
--- a/200-gcc-libiberty-Makefile.in.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff -aurp libiberty/Makefile.in libiberty/Makefile.in
---- libiberty/Makefile.in	2010-11-21 01:07:08.000000000 +0530
-+++ libiberty/Makefile.in	2011-06-21 12:26:09.000000000 +0530
-@@ -340,7 +340,8 @@ libiberty.html : $(srcdir)/libiberty.tex
- @MAINT@	echo stamp > stamp-functions
- 
- INSTALL_DEST = @INSTALL_DEST@
--install: install_to_$(INSTALL_DEST) install-subdir
-+#install: install_to_$(INSTALL_DEST) install-subdir
-+install:
- install-strip: install
- 
- .PHONY: install install-strip
diff --git a/300-gcc-fixedpoint-3-4-2010.patch b/300-gcc-fixedpoint-3-4-2010.patch
deleted file mode 100644
index 04c52d3..0000000
--- a/300-gcc-fixedpoint-3-4-2010.patch
+++ /dev/null
@@ -1,2755 +0,0 @@
-diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
---- gcc/config/avr/avr.c	2011-10-27 16:45:17.000000000 +0530
-+++ gcc/config/avr/avr.c	2011-10-27 16:55:55.000000000 +0530
-@@ -236,6 +236,19 @@ static const struct default_options avr_
- #undef TARGET_EXCEPT_UNWIND_INFO
- #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
- 
-+#undef TARGET_SCALAR_MODE_SUPPORTED_P
-+#define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
-+
-+ /* Implement TARGET_SCALAR_MODE_SUPPORTED_P.  */
-+ static bool
-+ avr_scalar_mode_supported_p (enum machine_mode mode)
-+ {
-+    if (ALL_FIXED_POINT_MODE_P (mode))
-+       return true;
-+ 
-+   return default_scalar_mode_supported_p (mode);
-+ }
-+ 
- struct gcc_target targetm = TARGET_INITIALIZER;
- 

- static void
-@@ -1767,9 +1780,9 @@ output_movqi (rtx insn, rtx operands[], 
- 
-   *l = 1;
-   
--  if (register_operand (dest, QImode))
-+  if (register_operand (dest, VOIDmode))
-     {
--      if (register_operand (src, QImode)) /* mov r,r */
-+      if (register_operand (src, VOIDmode)) /* mov r,r */
- 	{
- 	  if (test_hard_reg_class (STACK_REG, dest))
- 	    return AS2 (out,%0,%1);
-@@ -1857,9 +1870,9 @@ output_movhi (rtx insn, rtx operands[], 
-   if (!l)
-     l = &dummy;
-   
--  if (register_operand (dest, HImode))
-+  if (register_operand (dest, VOIDmode))
-     {
--      if (register_operand (src, HImode)) /* mov r,r */
-+      if (register_operand (src, VOIDmode)) /* mov r,r */
- 	{
- 	  if (test_hard_reg_class (STACK_REG, dest))
- 	    {
-@@ -2582,6 +2595,14 @@ output_movsisf(rtx insn, rtx operands[],
- 	{
- 	  if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
- 	    {
-+	      if (AVR_HAVE_MOVW 
-+	          && (UINTVAL (src) >> 16) == (UINTVAL (src) & 0xffff))
-+		{
-+		  *l = 3;
-+		  return  (AS2 (ldi,%A0,lo8(%1))  CR_TAB
-+		           AS2 (ldi,%B0,hi8(%1))  CR_TAB
-+		    	   AS2 (movw,%C0,%A0));
-+		}
- 	      *l = 4;
- 	      return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
- 		      AS2 (ldi,%B0,hi8(%1))  CR_TAB
-@@ -4527,6 +4548,196 @@ avr_rotate_bytes (rtx operands[])
-     return true;
- }
- 
-+/* Outputs instructions needed for fixed point conversion.  */
-+
-+const char *
-+fract_out (rtx insn ATTRIBUTE_UNUSED, rtx operands[], int intsigned, int *len)
-+{
-+  int i, k = 0;
-+  int sbit[2], ilen[2], flen[2], tlen[2];
-+  int rdest, rsource, offset;
-+  int start, end, dir;
-+  int hadbst = 0, hadlsl = 0;
-+  int clrword = -1, lastclr = 0, clr = 0;
-+  char buf[20];
-+
-+  if (!len)
-+    len = &k;
-+
-+  for (i = 0; i < 2; i++)
-+    {
-+      enum machine_mode mode = GET_MODE (operands[i]);
-+      tlen[i] = GET_MODE_SIZE (mode);
-+      if (SCALAR_INT_MODE_P (mode))
-+        {
-+          sbit[i] = intsigned;
-+          ilen[i] = GET_MODE_BITSIZE(mode) / 8;
-+          flen[i] = 0;
-+        }
-+      else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
-+        {
-+          sbit[i] = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
-+          ilen[i] = (GET_MODE_IBIT (mode) + 1) / 8;
-+          flen[i] = (GET_MODE_FBIT (mode) + 1) / 8;
-+        }
-+      else
-+        fatal_insn ("unsupported fixed-point conversion", insn);
-+    }
-+
-+  rdest = true_regnum (operands[0]);
-+  rsource = true_regnum (operands[1]);
-+  offset = flen[1] - flen[0];
-+
-+  /* Store the sign bit if the destination is a signed
-+     fract and the source has a sign in the integer part.  */
-+  if (sbit[0] && !ilen[0] && sbit[1] && ilen[1])
-+    {
-+      /* To avoid using bst and bld if the source and
-+         destination registers overlap we can use a single lsl
-+         since we don't care about preserving the source register.  */
-+      if (rdest < rsource + tlen[1] && rdest + tlen[0] > rsource)
-+        {
-+          sprintf (buf, "lsl r%d", rsource + tlen[1] - 1);
-+          hadlsl = 1;
-+        }
-+      else
-+        {
-+          sprintf (buf, "bst r%d, 7", rsource + tlen[1] - 1);
-+          hadbst = 1;
-+        }
-+      output_asm_insn (buf, operands);
-+      ++*len;
-+    }
-+
-+  /* Pick the correct direction.  */
-+  if (rdest < rsource + offset)
-+    {
-+      dir = 1;
-+      start = 0;
-+      end = tlen[0];
-+    }
-+  else
-+    {
-+      dir = -1;
-+      start = tlen[0] - 1;
-+      end = -1;
-+    }
-+
-+  /* Move registers into place, clearing registers that do not overlap.  */
-+  for (i = start; i != end; i += dir)
-+    {
-+      int destloc = rdest + i, sourceloc = rsource + i + offset;
-+      if (sourceloc < rsource || sourceloc >= rsource + tlen[1])
-+        {
-+          if (AVR_HAVE_MOVW && i+dir != end
-+              && (sourceloc+dir < rsource || sourceloc+dir >= rsource + tlen[1])
-+              && ((dir == 1 && !(destloc%2) && !(sourceloc%2))
-+                  || (dir == -1 && (destloc%2) && (sourceloc%2)))
-+              && clrword != -1)
-+            {
-+              sprintf (buf, "movw r%d, r%d", destloc&0xfe, clrword&0xfe);
-+              i += dir;
-+            }
-+          else
-+            {
-+              /* Do not clear the register if it is going to get
-+                 sign extended with a mov later.  */
-+              if (sbit[0] && sbit[1] && i != tlen[0] - 1 && i >= flen[0])
-+                continue;
-+
-+              sprintf (buf, "clr r%d", destloc);
-+              if (lastclr)
-+                clrword = destloc;
-+              clr=1;
-+            }
-+        }
-+      else if (destloc == sourceloc)
-+        continue;
-+      else
-+        if (AVR_HAVE_MOVW && i+dir != end
-+            && sourceloc+dir >= rsource && sourceloc+dir < rsource + tlen[1]
-+            && ((dir == 1 && !(destloc%2) && !(sourceloc%2))
-+                || (dir == -1 && (destloc%2) && (sourceloc%2))))
-+          {
-+            sprintf (buf, "movw r%d, r%d", destloc&0xfe, sourceloc&0xfe);
-+            i += dir;
-+          }
-+        else
-+          sprintf (buf, "mov r%d, r%d", destloc, sourceloc);
-+        
-+      output_asm_insn (buf, operands);
-+      ++*len;
-+
-+      lastclr = clr;
-+      clr = 0;
-+    }
-+
-+  /* Perform sign extension if needed.  */
-+  if (sbit[0] && sbit[1] && ilen[0] > ilen[1])
-+    {
-+      sprintf (buf, "sbrc r%d, 7", rdest+tlen[1]-1-offset);
-+      output_asm_insn (buf, operands);
-+      sprintf (buf, "com r%d", rdest+tlen[0]-1);
-+      output_asm_insn (buf, operands);
-+      *len += 2;
-+      /* Sign extend additional bytes.  */
-+      start = rdest + tlen[0] - 2;
-+      end = rdest + flen[0] + ilen[1] - 1;
-+      for (i = start; i != end; i--)
-+        {
-+          if (AVR_HAVE_MOVW && i != start && i-1 != end)
-+            sprintf (buf, "movw r%d, r%d", --i, rdest+tlen[0]-2);
-+          else
-+            sprintf (buf, "mov r%d, r%d", i, rdest+tlen[0]-1);
-+          output_asm_insn (buf, operands);
-+          ++*len;
-+        }
-+    }
-+
-+  /* Perform shifts, only needed if one operand
-+     is a signed fract, and the other is not.  */
-+  if (sbit[0] && !ilen[0] && (!sbit[1] || ilen[1]))
-+    {
-+      start = rdest+flen[0]-1;
-+      end = rdest + flen[0] - flen[1];
-+      if (end < rdest)
-+        end = rdest;
-+      for (i = start; i >= end; i--)
-+      {
-+        if (i == start && !hadlsl)
-+          sprintf (buf, "lsr r%d", i);
-+        else
-+          sprintf (buf, "ror r%d", i);
-+        output_asm_insn (buf, operands);
-+        ++*len;
-+      }
-+
-+      if (hadbst)
-+        {
-+          sprintf (buf, "bld r%d, 7", rdest + tlen[0] - 1);
-+          output_asm_insn (buf, operands);
-+          ++*len;
-+        }
-+    }
-+  else if (sbit[1] && !ilen[1] && (!sbit[0] || ilen[0]))
-+    {
-+      start = rdest + flen[0] - flen[1];
-+      if (start < rdest)
-+        start = rdest;
-+      for (i = start; i<rdest+flen[0]; i++)
-+        {
-+          if (i == start)
-+            sprintf (buf, "lsl r%d", i);
-+          else
-+            sprintf (buf, "rol r%d", i);
-+          output_asm_insn (buf, operands);
-+          ++*len;
-+        }
-+    }
-+
-+  return "";
-+}
-+
- /* Modifies the length assigned to instruction INSN
-  LEN is the initially computed length of the insn.  */
- 
-diff -Naurp gcc/config/avr/avr-fixed.md gcc/config/avr/avr-fixed.md
---- gcc/config/avr/avr-fixed.md	1970-01-01 05:30:00.000000000 +0530
-+++ gcc/config/avr/avr-fixed.md	2011-10-27 16:55:55.000000000 +0530
-@@ -0,0 +1,338 @@
-+;; -*- Mode: Scheme -*-
-+;;   This file contains instructions that support fixed-point operations
-+;;   for ATMEL AVR micro controllers.
-+;;   Copyright (C) 2009
-+;;   Free Software Foundation, Inc.
-+;;   Contributed by Sean D'Epagnier (sean at depagnier.com)
-+
-+;; This file is part of GCC.
-+
-+;; GCC is free software; you can redistribute it and/or modify
-+;; it under the terms of the GNU General Public License as published by
-+;; the Free Software Foundation; either version 3, or (at your option)
-+;; any later version.
-+
-+;; GCC is distributed in the hope that it will be useful,
-+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+;; GNU General Public License for more details.
-+
-+;; You should have received a copy of the GNU General Public License
-+;; along with GCC; see the file COPYING3.  If not see
-+;; <http://www.gnu.org/licenses/>.
-+
-+(define_mode_iterator ALLQQ [(QQ "") (UQQ "")])
-+(define_mode_iterator ALLHQ [(HQ "") (UHQ "")])
-+(define_mode_iterator ALLHA [(HA "") (UHA "")])
-+(define_mode_iterator ALLHQHA [(HQ "") (UHQ "") (HA "") (UHA "")])
-+(define_mode_iterator ALLSA [(SA "") (USA "")])
-+
-+;;; Conversions
-+
-+(define_mode_iterator FIXED1 [(QQ "") (UQQ "") (HQ "") (UHQ "")
-+                              (SQ "") (USQ "") (DQ "") (UDQ "")
-+                              (HA "") (UHA "") (SA "") (USA "")
-+                              (DA "") (UDA "") (TA "") (UTA "")
-+                              (QI "") (HI "") (SI "") (DI "")])
-+(define_mode_iterator FIXED2 [(QQ "") (UQQ "") (HQ "") (UHQ "")
-+                              (SQ "") (USQ "") (DQ "") (UDQ "")
-+                              (HA "") (UHA "") (SA "") (USA "")
-+                              (DA "") (UDA "") (TA "") (UTA "")
-+                              (QI "") (HI "") (SI "") (DI "")])
-+
-+(define_insn "fract<FIXED2:mode><FIXED1:mode>2"
-+  [(set (match_operand:FIXED1 0 "register_operand" "=r")
-+        (fract_convert:FIXED1 (match_operand:FIXED2 1 "register_operand" "r")))]
-+  ""
-+  "* return fract_out (insn, operands, 1, NULL);"
-+  [(set_attr "cc" "clobber")])
-+
-+(define_insn "fractuns<FIXED2:mode><FIXED1:mode>2"
-+  [(set (match_operand:FIXED1 0 "register_operand" "=r")
-+        (unsigned_fract_convert:FIXED1 (match_operand:FIXED2 1 "register_operand" "r")))]
-+  ""
-+  "* return fract_out (insn, operands, 0, NULL);"
-+  [(set_attr "cc" "clobber")])
-+
-+;;; Addition/Subtraction, mostly identical to integer versions
-+
-+(define_insn "add<ALLQQ:mode>3"
-+  [(set (match_operand:ALLQQ 0 "register_operand" "=r,d")
-+        (plus:ALLQQ (match_operand:ALLQQ 1 "register_operand" "%0,0")
-+                    (match_operand:ALLQQ 2 "nonmemory_operand" "r,i")))]
-+  ""
-+  "@
-+        add %0,%2
-+        subi %0,lo8(-(%2))"
-+  [(set_attr "length" "1,1")
-+   (set_attr "cc" "set_czn,set_czn")])
-+
-+(define_insn "sub<ALLQQ:mode>3"
-+  [(set (match_operand:ALLQQ 0 "register_operand" "=r,d")
-+        (minus:ALLQQ (match_operand:ALLQQ 1 "register_operand" "0,0")
-+                     (match_operand:ALLQQ 2 "nonmemory_operand" "r,i")))]
-+  ""
-+  "@
-+ 	sub %0,%2
-+ 	subi %0,lo8(%2)"
-+  [(set_attr "length" "1,1")
-+   (set_attr "cc" "set_czn,set_czn")])
-+
-+
-+(define_insn "add<ALLHQHA:mode>3"
-+  [(set (match_operand:ALLHQHA 0 "register_operand" "=r,d")
-+ 	(plus:ALLHQHA (match_operand:ALLHQHA 1 "register_operand" "%0,0")
-+                    (match_operand:ALLHQHA 2 "nonmemory_operand" "r,i")))]
-+  ""
-+  "@
-+ 	add %A0,%A2\;adc %B0,%B2
-+        subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))"
-+  [(set_attr "length" "2,2")
-+   (set_attr "cc" "set_n,set_czn")])
-+
-+(define_insn "sub<ALLHQHA:mode>3"
-+  [(set (match_operand:ALLHQHA 0 "register_operand" "=r,d")
-+        (minus:ALLHQHA (match_operand:ALLHQHA 1 "register_operand" "0,0")
-+		  (match_operand:ALLHQHA 2 "nonmemory_operand" "r,i")))]
-+  ""
-+  "@
-+	sub %A0,%A2\;sbc %B0,%B2
-+	subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
-+  [(set_attr "length" "2,2")
-+   (set_attr "cc" "set_czn,set_czn")])
-+
-+(define_insn "add<ALLSA:mode>3"
-+  [(set (match_operand:ALLSA 0 "register_operand" "=r,d")
-+ 	(plus:ALLSA (match_operand:ALLSA 1 "register_operand" "%0,0")
-+                    (match_operand:ALLSA 2 "nonmemory_operand" "r,i")))]
-+  ""
-+  "@
-+	add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
-+	subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))"
-+  [(set_attr "length" "4,4")
-+   (set_attr "cc" "set_n,set_czn")])
-+
-+(define_insn "sub<ALLSA:mode>3"
-+  [(set (match_operand:ALLSA 0 "register_operand" "=r,d")
-+        (minus:ALLSA (match_operand:ALLSA 1 "register_operand" "0,0")
-+		  (match_operand:ALLSA 2 "nonmemory_operand" "r,i")))]
-+  ""
-+  "@
-+	sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
-+	subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
-+  [(set_attr "length" "4,4")
-+   (set_attr "cc" "set_czn,set_czn")])
-+
-+;******************************************************************************
-+; mul
-+
-+(define_insn "mulqq3"
-+  [(set (match_operand:QQ 0 "register_operand" "=r")
-+	(mult:QQ (match_operand:QQ 1 "register_operand" "a")
-+		 (match_operand:QQ 2 "register_operand" "a")))]
-+  "AVR_HAVE_MUL"
-+  "fmuls %1,%2\;mov %0,r1\;clr r1"
-+  [(set_attr "length" "3")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "muluqq3"
-+  [(set (match_operand:UQQ 0 "register_operand" "=r")
-+	(mult:UQQ (match_operand:UQQ 1 "register_operand" "r")
-+                  (match_operand:UQQ 2 "register_operand" "r")))]
-+  "AVR_HAVE_MUL"
-+  "mul %1,%2\;mov %0,r1\;clr r1"
-+  [(set_attr "length" "3")
-+   (set_attr "cc" "clobber")])
-+
-+;; (reg:ALLHQ 20) not clobbered on the enhanced core.
-+;; use registers from 16-23 so we can use fmuls
-+;; All call-used registers clobbered otherwise - normal library call.
-+(define_expand "mul<ALLHQ:mode>3"
-+  [(set (reg:ALLHQ 22) (match_operand:ALLHQ 1 "register_operand" ""))
-+   (set (reg:ALLHQ 20) (match_operand:ALLHQ 2 "register_operand" ""))
-+   (parallel [(set (reg:ALLHQ 18) (mult:ALLHQ (reg:ALLHQ 22) (reg:ALLHQ 20)))
-+	      (clobber (reg:ALLHQ 22))])
-+   (set (match_operand:ALLHQ 0 "register_operand" "") (reg:ALLHQ 18))]
-+  "AVR_HAVE_MUL"
-+  "")
-+
-+(define_insn "*mul<ALLHQ:mode>3_enh_call"
-+  [(set (reg:ALLHQ 18) (mult:ALLHQ (reg:ALLHQ 22) (reg:ALLHQ 20)))
-+   (clobber (reg:ALLHQ 22))]
-+  "AVR_HAVE_MUL"
-+  "%~call __mul<ALLHQ:mode>3"
-+  [(set_attr "type" "xcall")
-+   (set_attr "cc" "clobber")])
-+
-+; Special calls for with and without mul.
-+(define_expand "mul<ALLHA:mode>3"
-+  [(set (reg:ALLHA 22) (match_operand:ALLHA 1 "register_operand" ""))
-+   (set (reg:ALLHA 20) (match_operand:ALLHA 2 "register_operand" ""))
-+   (parallel [(set (reg:ALLHA 18) (mult:ALLHA (reg:ALLHA 22) (reg:ALLHA 20)))
-+	      (clobber (reg:ALLHA 22))])
-+   (set (match_operand:ALLHA 0 "register_operand" "") (reg:ALLHA 18))]
-+  ""
-+  "
-+{
-+  if (!AVR_HAVE_MUL)
-+    {
-+      emit_insn (gen_mul<ALLHA:mode>3_call (operands[0], operands[1], operands[2]));
-+      DONE;
-+    }
-+}")
-+
-+(define_insn "*mul<ALLHA:mode>3_enh"
-+  [(set (reg:ALLHA 18) (mult:ALLHA (reg:ALLHA 22) (reg:ALLHA 20)))
-+   (clobber (reg:ALLHA 22))]
-+  "AVR_HAVE_MUL"
-+  "%~call __mul<ALLHA:mode>3"
-+  [(set_attr "type" "xcall")
-+   (set_attr "cc" "clobber")])
-+
-+; Without multiplier, clobbers both inputs, and needs a separate output register
-+(define_expand "mul<ALLHA:mode>3_call"
-+  [(set (reg:ALLHA 24) (match_operand:ALLHA 1 "register_operand" ""))
-+   (set (reg:ALLHA 22) (match_operand:ALLHA 2 "register_operand" ""))
-+   (parallel [(set (reg:ALLHA 18) (mult:ALLHA (reg:ALLHA 22) (reg:ALLHA 24)))
-+              (clobber (reg:ALLHA 22))
-+              (clobber (reg:ALLHA 24))])
-+   (set (match_operand:ALLHA 0 "register_operand" "") (reg:ALLHA 18))]
-+  "!AVR_HAVE_MUL"
-+  "")
-+
-+(define_insn "*mul<ALLHA:mode>3_call"
-+  [(set (reg:ALLHA 18) (mult:ALLHA (reg:ALLHA 22) (reg:ALLHA 24)))
-+   (clobber (reg:ALLHA 22))
-+   (clobber (reg:ALLHA 24))]
-+  "!AVR_HAVE_MUL"
-+  "%~call __mul<ALLHA:mode>3"
-+  [(set_attr "type" "xcall")
-+   (set_attr "cc" "clobber")])
-+
-+;; On the enhanced core, don't clobber either input, and use a separate output,
-+;; r2 is needed as a zero register since r1 is used for mul
-+(define_expand "mul<ALLSA:mode>3"
-+  [(set (reg:ALLSA 16) (match_operand:ALLSA 1 "register_operand" ""))
-+   (set (reg:ALLSA 20) (match_operand:ALLSA 2 "register_operand" ""))
-+   (parallel [(set (reg:ALLSA 24) (mult:ALLSA (reg:ALLSA 16) (reg:ALLSA 20)))
-+	      (clobber (reg:QI 15))])
-+   (set (match_operand:ALLSA 0 "register_operand" "") (reg:ALLSA 24))]
-+  ""
-+  "
-+{
-+  if (!AVR_HAVE_MUL)
-+    {
-+      emit_insn (gen_mul<ALLSA:mode>3_call (operands[0], operands[1], operands[2]));
-+      DONE;
-+    }
-+}")
-+
-+(define_insn "*mul<ALLSA:mode>3_enh"
-+  [(set (reg:ALLSA 24) (mult:ALLSA (reg:ALLSA 16) (reg:ALLSA 20)))
-+   (clobber (reg:QI 15))]
-+  "AVR_HAVE_MUL"
-+  "%~call __mul<ALLSA:mode>3"
-+  [(set_attr "type" "xcall")
-+   (set_attr "cc" "clobber")])
-+
-+; Without multiplier, clobbers both inputs, needs a separate output, and also
-+; needs two more scratch registers
-+(define_expand "mul<ALLSA:mode>3_call"
-+  [(set (reg:ALLSA 18) (match_operand:ALLSA 1 "register_operand" ""))
-+   (set (reg:ALLSA 24) (match_operand:ALLSA 2 "register_operand" ""))
-+   (parallel [(set (reg:ALLSA 14) (mult:ALLSA (reg:ALLSA 18) (reg:ALLSA 24)))
-+              (clobber (reg:ALLSA 18))
-+              (clobber (reg:ALLSA 24))
-+	      (clobber (reg:HI 22))])
-+   (set (match_operand:ALLSA 0 "register_operand" "") (reg:ALLSA 14))]
-+  "!AVR_HAVE_MUL"
-+  "")
-+
-+(define_insn "*mul<ALLSA:mode>3_call"
-+  [(set (reg:ALLSA 14) (mult:ALLSA (reg:ALLSA 18) (reg:ALLSA 24)))
-+   (clobber (reg:ALLSA 18))
-+   (clobber (reg:ALLSA 24))
-+   (clobber (reg:HI 22))]
-+  "!AVR_HAVE_MUL"
-+  "%~call __mul<ALLSA:mode>3"
-+  [(set_attr "type" "xcall")
-+   (set_attr "cc" "clobber")])
-+
-+; / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
-+; div
-+
-+(define_code_iterator usdiv [udiv div]) ; do signed and unsigned in one shot
-+
-+(define_expand "<usdiv:code><ALLQQ:mode>3"
-+  [(set (reg:ALLQQ 25) (match_operand:ALLQQ 1 "register_operand" ""))
-+   (set (reg:ALLQQ 22) (match_operand:ALLQQ 2 "register_operand" ""))
-+   (parallel [(set (reg:ALLQQ 24) (usdiv:ALLQQ (reg:ALLQQ 25) (reg:ALLQQ 22)))
-+	      (clobber (reg:ALLQQ 25))
-+	      (clobber (reg:QI 23))])
-+   (set (match_operand:ALLQQ 0 "register_operand" "") (reg:ALLQQ 24))]
-+  ""
-+  "")
-+
-+(define_insn "*<usdiv:code><ALLQQ:mode>3_call"
-+  [(set (reg:ALLQQ 24) (usdiv:ALLQQ (reg:ALLQQ 25) (reg:ALLQQ 22)))
-+   (clobber (reg:ALLQQ 25))
-+   (clobber (reg:QI 23))]
-+  ""
-+  "%~call __<usdiv:code><ALLQQ:mode>3"
-+  [(set_attr "type" "xcall")
-+   (set_attr "cc" "clobber")])
-+
-+(define_expand "<usdiv:code><ALLHQHA:mode>3"
-+  [(set (reg:ALLHQHA 26) (match_operand:ALLHQHA 1 "register_operand" ""))
-+   (set (reg:ALLHQHA 22) (match_operand:ALLHQHA 2 "register_operand" ""))
-+   (parallel [(set (reg:ALLHQHA 24) (usdiv:ALLHQHA (reg:ALLHQHA 26) (reg:ALLHQHA 22)))
-+	      (clobber (reg:ALLHQHA 26))
-+	      (clobber (reg:QI 21))])
-+   (set (match_operand:ALLHQHA 0 "register_operand" "") (reg:ALLHQHA 24))]
-+  ""
-+  "")
-+
-+(define_insn "*<usdiv:code><ALLHQHA:mode>3_call"
-+  [(set (reg:ALLHQHA 24) (usdiv:ALLHQHA (reg:ALLHQHA 26) (reg:ALLHQHA 22)))
-+   (clobber (reg:ALLHQHA 26))
-+   (clobber (reg:QI 21))]
-+  ""
-+  "%~call __<usdiv:code><ALLHQHA:mode>3"
-+  [(set_attr "type" "xcall")
-+   (set_attr "cc" "clobber")])
-+
-+; note the first parameter gets passed in already offset by 2 bytes
-+(define_expand "<usdiv:code><ALLSA:mode>3"
-+  [(set (reg:ALLSA 24) (match_operand:ALLSA 1 "register_operand" ""))
-+   (set (reg:ALLSA 18) (match_operand:ALLSA 2 "register_operand" ""))
-+   (parallel [(set (reg:ALLSA 22) (usdiv:ALLSA (reg:ALLSA 24) (reg:ALLSA 18)))
-+	      (clobber (reg:HI 26))
-+              (clobber (reg:HI 30))])
-+   (set (match_operand:ALLSA 0 "register_operand" "") (reg:ALLSA 22))]
-+  ""
-+  "")
-+
-+(define_insn "*<usdiv:code><ALLSA:mode>3_call"
-+  [(set (reg:ALLSA 22) (usdiv:ALLSA (reg:ALLSA 24) (reg:ALLSA 18)))
-+   (clobber (reg:HI 26))
-+   (clobber (reg:HI 30))]
-+  ""
-+  "%~call __<usdiv:code><ALLSA:mode>3"
-+  [(set_attr "type" "xcall")
-+   (set_attr "cc" "clobber")])
-+
-+
-+;; abs must be defined for fixed types for correct operation
-+
-+;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
-+
-+;; abs
-+
-+(define_insn "abs<ALLQQ:mode>2"
-+  [(set (match_operand:ALLQQ 0 "register_operand" "=r")
-+        (abs:ALLQQ (match_operand:ALLQQ 1 "register_operand" "0")))]
-+  ""
-+  "sbrc %0,7
-+	neg %0"
-+  [(set_attr "length" "2")
-+   (set_attr "cc" "clobber")])
-diff -Naurp gcc/config/avr/avr.md gcc/config/avr/avr.md
---- gcc/config/avr/avr.md	2011-10-27 16:45:17.000000000 +0530
-+++ gcc/config/avr/avr.md	2011-10-27 16:55:55.000000000 +0530
-@@ -65,6 +65,15 @@
- (include "predicates.md")
- (include "constraints.md")
-   
-+; fixed-point instructions.
-+(include "avr-fixed.md")
-+(define_mode_iterator ALLQ [(QI "") (QQ "") (UQQ "")])
-+(define_mode_iterator ALLH [(HI "") (HQ "") (UHQ "") (HA "") (UHA "")])
-+(define_mode_iterator ALLS [(SI "") (SA "") (USA "")])
-+(define_mode_iterator ALLQS [(QI "") (QQ "") (UQQ "")
-+			     (HI "") (HQ "") (UHQ "") (HA "") (UHA "")
-+			     (SI "") (SA "") (USA "")])
-+
- ;; Condition code settings.
- (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
-   (const_string "none"))
-@@ -179,28 +188,27 @@
-   DONE;
- })
- 
--
--(define_insn "*pushqi"
--  [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
--        (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
-+(define_insn "*push<ALLQ:mode>"
-+   [(set (mem:ALLQ (post_dec:HI (reg:HI REG_SP)))
-+         (match_operand:ALLQ 0 "reg_or_0_operand" "r,L"))]
-   ""
-   "@
- 	push %0
- 	push __zero_reg__"
-   [(set_attr "length" "1,1")])
- 
--(define_insn "*pushhi"
--  [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
--        (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
-+(define_insn "*push<ALLH:mode>"
-+   [(set (mem:ALLH (post_dec:HI (reg:HI REG_SP)))
-+         (match_operand:ALLH 0 "reg_or_0_operand" "r,L"))]
-   ""
-   "@
- 	push %B0\;push %A0
- 	push __zero_reg__\;push __zero_reg__"
-   [(set_attr "length" "2,2")])
- 
--(define_insn "*pushsi"
--  [(set (mem:SI (post_dec:HI (reg:HI REG_SP)))
--        (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
-+(define_insn "*push<ALLS:mode>"
-+   [(set (mem:ALLS (post_dec:HI (reg:HI REG_SP)))
-+         (match_operand:ALLS 0 "reg_or_0_operand" "r,L"))]
-   ""
-   "@
- 	push %D0\;push %C0\;push %B0\;push %A0
-@@ -226,21 +234,21 @@
- ;; are call-saved registers, and most of LD_REGS are call-used registers,
- ;; so this may still be a win for registers live across function calls.
- 
--(define_expand "movqi"
--  [(set (match_operand:QI 0 "nonimmediate_operand" "")
--	(match_operand:QI 1 "general_operand" ""))]
-+(define_expand "mov<ALLQ:mode>"
-+   [(set (match_operand:ALLQ 0 "nonimmediate_operand" "")
-+ 	(match_operand:ALLQ 1 "general_operand" ""))]
-   ""
-   "/* One of the ops has to be in a register.  */
--   if (!register_operand(operand0, QImode)
--       && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
--       operands[1] = copy_to_mode_reg(QImode, operand1);
-+    if (!register_operand(operand0, <ALLQ:MODE>mode)
-+        && ! (register_operand(operand1, <ALLQ:MODE>mode) || const0_rtx == operand1))
-+        operands[1] = copy_to_mode_reg(<ALLQ:MODE>mode, operand1);
-   ")
- 
--(define_insn "*movqi"
--  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
--	(match_operand:QI 1 "general_operand"       "rL,i,rL,Qm,r,q,i"))]
--  "(register_operand (operands[0],QImode)
--    || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
-+(define_insn "*mov<ALLQ:mode>"
-+   [(set (match_operand:ALLQ 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
-+ 	(match_operand:ALLQ 1 "general_operand"       "r,i,rL,Qm,r,q,i"))]
-+   "(register_operand (operands[0],<ALLQ:MODE>mode)
-+     || register_operand (operands[1], <ALLQ:MODE>mode) || const0_rtx == operands[1])"
-   "* return output_movqi (insn, operands, NULL);"
-   [(set_attr "length" "1,1,5,5,1,1,4")
-    (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
-@@ -272,17 +280,17 @@
- ;;============================================================================
- ;; move word (16 bit)
- 
--(define_expand "movhi"
--  [(set (match_operand:HI 0 "nonimmediate_operand" "")
--        (match_operand:HI 1 "general_operand"       ""))]
-+(define_expand "mov<ALLH:mode>"
-+  [(set (match_operand:ALLH 0 "nonimmediate_operand" "")
-+        (match_operand:ALLH 1 "general_operand"       ""))]
-   ""
-   "
- {
-    /* One of the ops has to be in a register.  */
--  if (!register_operand(operand0, HImode)
--      && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
-+  if (!register_operand(operand0, <ALLH:MODE>mode)
-+      && !(register_operand(operand1, <ALLH:MODE>mode) || const0_rtx == operands[1]))
-     {
--      operands[1] = copy_to_mode_reg(HImode, operand1);
-+      operands[1] = copy_to_mode_reg(<ALLH:MODE>mode, operand1);
-     }
- }")
- 
-@@ -337,20 +345,20 @@
-   [(set_attr "length" "4")
-    (set_attr "cc" "none")])
- 
--(define_insn "*movhi"
--  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
--        (match_operand:HI 1 "general_operand"       "rL,m,rL,i,i,r,q"))]
--  "(register_operand (operands[0],HImode)
--    || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
-+(define_insn "*mov<ALLH:mode>"
-+  [(set (match_operand:ALLH 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
-+        (match_operand:ALLH 1 "general_operand"       "r,m,rL,i,i,r,q"))]
-+  "(register_operand (operands[0],<ALLH:MODE>mode)
-+    || register_operand (operands[1],<ALLH:MODE>mode) || const0_rtx == operands[1])"
-   "* return output_movhi (insn, operands, NULL);"
-   [(set_attr "length" "2,6,7,2,6,5,2")
-    (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
- 
- (define_peephole2 ; movw
--  [(set (match_operand:QI 0 "even_register_operand" "")
--        (match_operand:QI 1 "even_register_operand" ""))
--   (set (match_operand:QI 2 "odd_register_operand" "")
--        (match_operand:QI 3 "odd_register_operand" ""))]
-+  [(set (match_operand:ALLQ 0 "even_register_operand" "")
-+        (match_operand:ALLQ 1 "even_register_operand" ""))
-+   (set (match_operand:ALLQ 2 "odd_register_operand" "")
-+        (match_operand:ALLQ 3 "odd_register_operand" ""))]
-   "(AVR_HAVE_MOVW
-     && REGNO (operands[0]) == REGNO (operands[2]) - 1
-     && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
-@@ -361,10 +369,10 @@
-   })
- 
- (define_peephole2 ; movw_r
--  [(set (match_operand:QI 0 "odd_register_operand" "")
--        (match_operand:QI 1 "odd_register_operand" ""))
--   (set (match_operand:QI 2 "even_register_operand" "")
--        (match_operand:QI 3 "even_register_operand" ""))]
-+  [(set (match_operand:ALLQ 0 "odd_register_operand" "")
-+        (match_operand:ALLQ 1 "odd_register_operand" ""))
-+   (set (match_operand:ALLQ 2 "even_register_operand" "")
-+        (match_operand:ALLQ 3 "even_register_operand" ""))]
-   "(AVR_HAVE_MOVW
-     && REGNO (operands[2]) == REGNO (operands[0]) - 1
-     && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
-@@ -377,26 +385,24 @@
- ;;==========================================================================
- ;; move double word (32 bit)
- 
--(define_expand "movsi"
--  [(set (match_operand:SI 0 "nonimmediate_operand" "")
--        (match_operand:SI 1 "general_operand"  ""))]
-+(define_expand "mov<ALLS:mode>"
-+  [(set (match_operand:ALLS 0 "nonimmediate_operand" "")
-+        (match_operand:ALLS 1 "general_operand"  ""))]
-   ""
-   "
- {
-   /* One of the ops has to be in a register.  */
--  if (!register_operand (operand0, SImode)
--      && !(register_operand (operand1, SImode) || const0_rtx == operand1))
-+  if (!register_operand (operand0, <ALLS:MODE>mode)
-+      && !(register_operand (operand1, <ALLS:MODE>mode) || const0_rtx == operand1))
-     {
--      operands[1] = copy_to_mode_reg (SImode, operand1);
-+      operands[1] = copy_to_mode_reg (<ALLS:MODE>mode, operand1);
-     }
- }")
- 
--
--
- (define_peephole2 ; movsi_lreg_const
-   [(match_scratch:QI 2 "d")
--   (set (match_operand:SI 0 "l_register_operand" "")
--        (match_operand:SI 1 "immediate_operand" ""))
-+   (set (match_operand:ALLS 0 "l_register_operand" "")
-+        (match_operand:ALLS 1 "immediate_operand" ""))
-    (match_dup 2)]
-   "(operands[1] != const0_rtx
-     && operands[1] != constm1_rtx)"
-@@ -406,8 +412,8 @@
- 
- ;; '*' because it is not used in rtl generation.
- (define_insn "*reload_insi"
--  [(set (match_operand:SI 0 "register_operand" "=r")
--        (match_operand:SI 1 "immediate_operand" "i"))
-+  [(set (match_operand:ALLS 0 "register_operand" "=r")
-+        (match_operand:ALLS 1 "immediate_operand" "i"))
-    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
-   "reload_completed"
-   "* return output_reload_insisf (insn, operands, NULL);"
-@@ -415,11 +421,11 @@
-    (set_attr "cc" "none")])
- 
- 
--(define_insn "*movsi"
--  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
--        (match_operand:SI 1 "general_operand"       "r,L,Qm,rL,i,i"))]
--  "(register_operand (operands[0],SImode)
--    || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
-+(define_insn "*mov<ALLS:mode>"
-+  [(set (match_operand:ALLS 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
-+        (match_operand:ALLS 1 "general_operand"       "r,L,Qm,rL,i,i"))]
-+  "(register_operand (operands[0],<ALLS:MODE>mode)
-+    || register_operand (operands[1],<ALLS:MODE>mode) || const0_rtx == operands[1])"
-   "* return output_movsisf (insn, operands, NULL);"
-   [(set_attr "length" "4,4,8,9,4,10")
-    (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
-@@ -956,23 +962,54 @@
-   [(set_attr "type" "xcall")
-    (set_attr "cc" "clobber")])
- 
--(define_insn "mulqihi3"
-+;; Define code iterators
-+(define_code_iterator any_extend [sign_extend zero_extend])
-+(define_code_attr s [(sign_extend "s") (zero_extend "")])
-+(define_code_attr u [(sign_extend "") (zero_extend "u")])
-+(define_code_attr su [(sign_extend "s") (zero_extend "u")])
-+
-+(define_insn "<any_extend:su>mulqi3_highpart"
-+  [(set (match_operand:QI 0 "register_operand" "=r")
-+	(truncate:QI
-+	 (lshiftrt:HI
-+	  (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "d"))
-+		   (any_extend:HI (match_operand:QI 2 "register_operand" "d")))
-+	  (const_int 8))))]
-+  "AVR_HAVE_MUL && !optimize_size"
-+  "mul<any_extend:s> %1,%2
-+	mov %0,r1
-+	clr r1"
-+  [(set_attr "length" "3")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "<any_extend:u>mulqihi3"
-   [(set (match_operand:HI 0 "register_operand" "=r")
--	(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
--		 (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
-+	(mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "d"))
-+		 (any_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
-   "AVR_HAVE_MUL"
--  "muls %1,%2
-+  "mul<any_extend:s> %1,%2
- 	movw %0,r0
- 	clr r1"
-   [(set_attr "length" "3")
-    (set_attr "cc" "clobber")])
- 
--(define_insn "umulqihi3"
-+(define_insn "*sumulqihi3"
-   [(set (match_operand:HI 0 "register_operand" "=r")
--	(mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
--		 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
-+	(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
-+		 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
-   "AVR_HAVE_MUL"
--  "mul %1,%2
-+  "mulsu %1,%2
-+	movw %0,r0
-+	clr r1"
-+  [(set_attr "length" "3")
-+   (set_attr "cc" "clobber")])
-+
-+(define_insn "*usmulqihi3"
-+  [(set (match_operand:HI 0 "register_operand" "=r")
-+	(mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
-+		 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
-+  "AVR_HAVE_MUL"
-+  "mulsu %2,%1
- 	movw %0,r0
- 	clr r1"
-   [(set_attr "length" "3")
-@@ -1026,6 +1063,50 @@
-   [(set_attr "type" "xcall")
-    (set_attr "cc" "clobber")])
- 
-+(define_expand "<any_extend:u>mulhisi3"
-+  [(set (reg:HI 18) (match_operand:SI 1 "register_operand" ""))
-+   (set (reg:HI 20) (match_operand:SI 2 "register_operand" ""))
-+   (set (reg:SI 22)
-+	(mult:SI (any_extend:SI (reg:HI 18))
-+		 (any_extend:SI (reg:HI 20))))
-+   (set (match_operand:SI 0 "register_operand" "") (reg:SI 22))]
-+  "!optimize_size"
-+  "")
-+
-+(define_insn "*<any_extend:u>mulhisi3_call"
-+  [(set (reg:SI 22)
-+	(mult:SI (any_extend:SI (reg:HI 18))
-+		 (any_extend:SI (reg:HI 20))))]
-+  "!optimize_size"
-+  "%~call __<any_extend:u>mulhisi3"
-+  [(set_attr "type" "xcall")
-+   (set_attr "cc" "clobber")])
-+
-+(define_expand "<any_extend:su>mulhi3_highpart"
-+  [(set (reg:HI 18) (match_operand:HI 1 "register_operand" ""))
-+   (set (reg:HI 20) (match_operand:HI 2 "register_operand" ""))
-+   (set (reg:HI 24) (truncate:HI (lshiftrt:SI
-+				  (mult:SI (any_extend:SI (reg:HI 18))
-+					   (any_extend:SI (reg:HI 20)))
-+				  (const_int 16))))
-+   (set (match_operand:SI 0 "register_operand" "") (reg:HI 24))]
-+  "AVR_HAVE_MUL"
-+  "")
-+
-+(define_insn_and_split "*<any_extend:su>mulhi3_highpart_call"
-+  [(set (reg:HI 24) (truncate:HI (lshiftrt:SI
-+				  (mult:SI (any_extend:SI (reg:HI 18))
-+					   (any_extend:SI (reg:HI 20)))
-+				  (const_int 16))))]
-+  "AVR_HAVE_MUL"
-+  ""
-+  ""
-+  [(set (reg:SI 22)
-+	(mult:SI (any_extend:SI (reg:HI 18))
-+		 (any_extend:SI (reg:HI 20))))
-+   (clobber (reg:HI 22))]
-+  "")
-+
- ;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
- ;; All call-used registers clobbered otherwise - normal library call.
- (define_expand "mulsi3"
-@@ -1574,9 +1655,9 @@
- ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
- ;; arithmetic shift left
- 
--(define_expand "ashlqi3"
--  [(set (match_operand:QI 0 "register_operand"            "")
--	(ashift:QI (match_operand:QI 1 "register_operand" "")
-+(define_expand "ashl<ALLQ:mode>3"
-+  [(set (match_operand:ALLQ 0 "register_operand"            "")
-+	(ashift:ALLQ (match_operand:ALLQ 1 "register_operand" "")
- 		   (match_operand:QI 2 "general_operand"  "")))]
-   ""
-   "")
-@@ -1610,27 +1691,27 @@
-    (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
-   "")
- 
--(define_insn "*ashlqi3"
--  [(set (match_operand:QI 0 "register_operand"           "=r,r,r,r,!d,r,r")
--	(ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
-+(define_insn "*ashl<ALLQ:mode>3"
-+  [(set (match_operand:ALLQ 0 "register_operand"           "=r,r,r,r,!d,r,r")
-+	(ashift:ALLQ (match_operand:ALLQ 1 "register_operand" "0,0,0,0,0,0,0")
- 		   (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
-   ""
-   "* return ashlqi3_out (insn, operands, NULL);"
-   [(set_attr "length" "5,0,1,2,4,6,9")
-    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
- 
--(define_insn "ashlhi3"
--  [(set (match_operand:HI 0 "register_operand"           "=r,r,r,r,r,r,r")
--	(ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
-+(define_insn "ashl<ALLH:mode>3"
-+  [(set (match_operand:ALLH 0 "register_operand"           "=r,r,r,r,r,r,r")
-+	(ashift:ALLH (match_operand:ALLH 1 "register_operand" "0,0,0,r,0,0,0")
- 		   (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
-   ""
-   "* return ashlhi3_out (insn, operands, NULL);"
-   [(set_attr "length" "6,0,2,2,4,10,10")
-    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
- 
--(define_insn "ashlsi3"
--  [(set (match_operand:SI 0 "register_operand"           "=r,r,r,r,r,r,r")
--	(ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
-+(define_insn "ashl<ALLS:mode>3"
-+  [(set (match_operand:ALLS 0 "register_operand"           "=r,r,r,r,r,r,r")
-+	(ashift:ALLS (match_operand:ALLS 1 "register_operand" "0,0,0,r,0,0,0")
- 		   (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
-   ""
-   "* return ashlsi3_out (insn, operands, NULL);"
-@@ -1676,17 +1757,17 @@
- 
- (define_peephole2
-   [(match_scratch:QI 3 "d")
--   (set (match_operand:HI 0 "register_operand" "")
--	(ashift:HI (match_operand:HI 1 "register_operand" "")
-+   (set (match_operand:ALLH 0 "register_operand" "")
-+	(ashift:ALLH (match_operand:ALLH 1 "register_operand" "")
- 		   (match_operand:QI 2 "const_int_operand" "")))]
-   ""
--  [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
-+  [(parallel [(set (match_dup 0) (ashift:ALLH (match_dup 1) (match_dup 2)))
- 	      (clobber (match_dup 3))])]
-   "")
- 
--(define_insn "*ashlhi3_const"
--  [(set (match_operand:HI 0 "register_operand"            "=r,r,r,r,r")
--	(ashift:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
-+(define_insn "*ashl<ALLH:mode>3_const"
-+  [(set (match_operand:ALLH 0 "register_operand"            "=r,r,r,r,r")
-+	(ashift:ALLH (match_operand:ALLH 1 "register_operand"  "0,0,r,0,0")
- 		   (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
-    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
-   "reload_completed"
-@@ -1696,17 +1777,17 @@
- 
- (define_peephole2
-   [(match_scratch:QI 3 "d")
--   (set (match_operand:SI 0 "register_operand" "")
--	(ashift:SI (match_operand:SI 1 "register_operand" "")
-+   (set (match_operand:ALLS 0 "register_operand" "")
-+	(ashift:ALLS (match_operand:ALLS 1 "register_operand" "")
- 		   (match_operand:QI 2 "const_int_operand" "")))]
-   ""
--  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
-+  [(parallel [(set (match_dup 0) (ashift:ALLS (match_dup 1) (match_dup 2)))
- 	      (clobber (match_dup 3))])]
-   "")
- 
--(define_insn "*ashlsi3_const"
--  [(set (match_operand:SI 0 "register_operand"            "=r,r,r,r")
--	(ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
-+(define_insn "*ashl<ALLS:mode>3_const"
-+  [(set (match_operand:ALLS 0 "register_operand"            "=r,r,r,r")
-+	(ashift:ALLS (match_operand:ALLS 1 "register_operand"  "0,0,r,0")
- 		   (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
-    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
-   "reload_completed"
-@@ -1717,27 +1798,27 @@
- ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
- ;; arithmetic shift right
- 
--(define_insn "ashrqi3"
--  [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
--	(ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
-+(define_insn "ashr<ALLQ:mode>3"
-+  [(set (match_operand:ALLQ 0 "register_operand" "=r,r,r,r,r,r")
-+	(ashiftrt:ALLQ (match_operand:ALLQ 1 "register_operand" "0,0,0,0,0,0")
- 		     (match_operand:QI 2 "general_operand"  "r,L,P,K,n,Qm")))]
-   ""
-   "* return ashrqi3_out (insn, operands, NULL);"
-   [(set_attr "length" "5,0,1,2,5,9")
-    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
- 
--(define_insn "ashrhi3"
--  [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
--	(ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
-+(define_insn "ashr<ALLH:mode>3"
-+  [(set (match_operand:ALLH 0 "register_operand"             "=r,r,r,r,r,r,r")
-+	(ashiftrt:ALLH (match_operand:ALLH 1 "register_operand" "0,0,0,r,0,0,0")
- 		     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
-   ""
-   "* return ashrhi3_out (insn, operands, NULL);"
-   [(set_attr "length" "6,0,2,4,4,10,10")
-    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
- 
--(define_insn "ashrsi3"
--  [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
--	(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
-+(define_insn "ashr<ALLS:mode>3"
-+  [(set (match_operand:ALLS 0 "register_operand"             "=r,r,r,r,r,r,r")
-+	(ashiftrt:ALLS (match_operand:ALLS 1 "register_operand" "0,0,0,r,0,0,0")
- 		     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
-   ""
-   "* return ashrsi3_out (insn, operands, NULL);"
-@@ -1748,17 +1829,17 @@
- 
- (define_peephole2
-   [(match_scratch:QI 3 "d")
--   (set (match_operand:HI 0 "register_operand" "")
--	(ashiftrt:HI (match_operand:HI 1 "register_operand" "")
-+   (set (match_operand:ALLH 0 "register_operand" "")
-+	(ashiftrt:ALLH (match_operand:ALLH 1 "register_operand" "")
- 		     (match_operand:QI 2 "const_int_operand" "")))]
-   ""
--  [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
-+  [(parallel [(set (match_dup 0) (ashiftrt:ALLH (match_dup 1) (match_dup 2)))
- 	      (clobber (match_dup 3))])]
-   "")
- 
- (define_insn "*ashrhi3_const"
--  [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
--	(ashiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
-+  [(set (match_operand:ALLH 0 "register_operand"              "=r,r,r,r,r")
-+	(ashiftrt:ALLH (match_operand:ALLH 1 "register_operand"  "0,0,r,0,0")
- 		     (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
-    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
-   "reload_completed"
-@@ -1768,17 +1849,17 @@
- 
- (define_peephole2
-   [(match_scratch:QI 3 "d")
--   (set (match_operand:SI 0 "register_operand" "")
--	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
-+   (set (match_operand:ALLS 0 "register_operand" "")
-+	(ashiftrt:ALLS (match_operand:ALLS 1 "register_operand" "")
- 		     (match_operand:QI 2 "const_int_operand" "")))]
-   ""
--  [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
-+  [(parallel [(set (match_dup 0) (ashiftrt:ALLS (match_dup 1) (match_dup 2)))
- 	      (clobber (match_dup 3))])]
-   "")
- 
- (define_insn "*ashrsi3_const"
--  [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
--	(ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
-+  [(set (match_operand:ALLS 0 "register_operand"              "=r,r,r,r")
-+	(ashiftrt:ALLS (match_operand:ALLS 1 "register_operand"  "0,0,r,0")
- 		     (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
-    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
-   "reload_completed"
-@@ -1789,54 +1870,54 @@
- ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
- ;; logical shift right
- 
--(define_expand "lshrqi3"
--  [(set (match_operand:QI 0 "register_operand"              "")
--	(lshiftrt:QI (match_operand:QI 1 "register_operand" "")
--		     (match_operand:QI 2 "general_operand"  "")))]
-+(define_expand "lshr<ALLQ:mode>3"
-+  [(set (match_operand:ALLQ 0 "register_operand"              "")
-+	(lshiftrt:ALLQ (match_operand:ALLQ 1 "register_operand" "")
-+		     (match_operand:ALLQ 2 "general_operand"  "")))]
-   ""
-   "")
- 
- (define_split	; lshrqi3_const4
--  [(set (match_operand:QI 0 "d_register_operand" "")
--	(lshiftrt:QI (match_dup 0)
-+  [(set (match_operand:ALLQ 0 "d_register_operand" "")
-+	(lshiftrt:ALLQ (match_dup 0)
- 		     (const_int 4)))]
-   ""
--  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
--   (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
-+  [(set (match_dup 0) (rotate:ALLQ (match_dup 0) (const_int 4)))
-+   (set (match_dup 0) (and:ALLQ (match_dup 0) (const_int 15)))]
-   "")
- 
- (define_split	; lshrqi3_const5
--  [(set (match_operand:QI 0 "d_register_operand" "")
--	(lshiftrt:QI (match_dup 0)
-+  [(set (match_operand:ALLQ 0 "d_register_operand" "")
-+	(lshiftrt:ALLQ (match_dup 0)
- 		     (const_int 5)))]
-   ""
--  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
--   (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
--   (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
-+  [(set (match_dup 0) (rotate:ALLQ (match_dup 0) (const_int 4)))
-+   (set (match_dup 0) (lshiftrt:ALLQ (match_dup 0) (const_int 1)))
-+   (set (match_dup 0) (and:ALLQ (match_dup 0) (const_int 7)))]
-   "")
- 
- (define_split	; lshrqi3_const6
--  [(set (match_operand:QI 0 "d_register_operand" "")
--	(lshiftrt:QI (match_dup 0)
-+  [(set (match_operand:ALLQ 0 "d_register_operand" "")
-+	(lshiftrt:ALLQ (match_dup 0)
- 		     (const_int 6)))]
-   ""
--  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
--   (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
--   (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
-+  [(set (match_dup 0) (rotate:ALLQ (match_dup 0) (const_int 4)))
-+   (set (match_dup 0) (lshiftrt:ALLQ (match_dup 0) (const_int 2)))
-+   (set (match_dup 0) (and:ALLQ (match_dup 0) (const_int 3)))]
-   "")
- 
- (define_insn "*lshrqi3"
--  [(set (match_operand:QI 0 "register_operand"             "=r,r,r,r,!d,r,r")
--	(lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
--		     (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
-+  [(set (match_operand:ALLQ 0 "register_operand"             "=r,r,r,r,!d,r,r")
-+	(lshiftrt:ALLQ (match_operand:ALLQ 1 "register_operand" "0,0,0,0,0,0,0")
-+		     (match_operand:ALLQ 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
-   ""
-   "* return lshrqi3_out (insn, operands, NULL);"
-   [(set_attr "length" "5,0,1,2,4,6,9")
-    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
- 
--(define_insn "lshrhi3"
--  [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
--	(lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
-+(define_insn "lshr<ALLH:mode>3"
-+  [(set (match_operand:ALLH 0 "register_operand"             "=r,r,r,r,r,r,r")
-+	(lshiftrt:ALLH (match_operand:ALLH 1 "register_operand" "0,0,0,r,0,0,0")
- 		     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
-   ""
-   "* return lshrhi3_out (insn, operands, NULL);"
-@@ -1891,17 +1972,17 @@
- 
- (define_peephole2
-   [(match_scratch:QI 3 "d")
--   (set (match_operand:HI 0 "register_operand" "")
--	(lshiftrt:HI (match_operand:HI 1 "register_operand" "")
-+   (set (match_operand:ALLH 0 "register_operand" "")
-+	(lshiftrt:ALLH (match_operand:ALLH 1 "register_operand" "")
- 		     (match_operand:QI 2 "const_int_operand" "")))]
-   ""
--  [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
-+  [(parallel [(set (match_dup 0) (lshiftrt:ALLH (match_dup 1) (match_dup 2)))
- 	      (clobber (match_dup 3))])]
-   "")
- 
--(define_insn "*lshrhi3_const"
--  [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
--	(lshiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
-+(define_insn "*lshr<ALLH:mode>3_const"
-+  [(set (match_operand:ALLH 0 "register_operand"              "=r,r,r,r,r")
-+	(lshiftrt:ALLH (match_operand:ALLH 1 "register_operand"  "0,0,r,0,0")
- 		     (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
-    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
-   "reload_completed"
-@@ -1919,9 +2000,9 @@
- 	      (clobber (match_dup 3))])]
-   "")
- 
--(define_insn "*lshrsi3_const"
--  [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
--	(lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
-+(define_insn "*lshr<ALLS:mode>3_const"
-+  [(set (match_operand:ALLS 0 "register_operand"              "=r,r,r,r")
-+	(lshiftrt:ALLS (match_operand:ALLS 1 "register_operand"  "0,0,r,0")
- 		     (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
-    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
-   "reload_completed"
-@@ -2171,27 +2252,27 @@
- ;; compare
- 
- ; Optimize negated tests into reverse compare if overflow is undefined.
--(define_insn "*negated_tstqi"
-+(define_insn "*negated_tst<ALLQ:mode>"
-   [(set (cc0)
--        (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
-+        (compare (neg:ALLQ (match_operand:ALLQ 0 "register_operand" "r"))
- 		 (const_int 0)))]
-   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
-   "cp __zero_reg__,%0"
-   [(set_attr "cc" "compare")
-    (set_attr "length" "1")])
- 
--(define_insn "*reversed_tstqi"
-+(define_insn "*reversed_tst<ALLQ:mode>"
-   [(set (cc0)
-         (compare (const_int 0)
--		 (match_operand:QI 0 "register_operand" "r")))]
-+		 (match_operand:ALLQ 0 "register_operand" "r")))]
-   ""
-   "cp __zero_reg__,%0"
- [(set_attr "cc" "compare")
-  (set_attr "length" "2")])
- 
--(define_insn "*negated_tsthi"
-+(define_insn "*negated_tst<ALLH:mode>"
-   [(set (cc0)
--        (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
-+        (compare (neg:ALLH (match_operand:ALLH 0 "register_operand" "r"))
- 		 (const_int 0)))]
-   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
-   "cp __zero_reg__,%A0
-@@ -2201,10 +2282,10 @@
- 
- ;; Leave here the clobber used by the cmphi pattern for simplicity, even
- ;; though it is unused, because this pattern is synthesized by avr_reorg.
--(define_insn "*reversed_tsthi"
-+(define_insn "*reversed_tst<ALLH:mode>"
-   [(set (cc0)
-         (compare (const_int 0)
--		 (match_operand:HI 0 "register_operand" "r")))
-+		 (match_operand:ALLH 0 "register_operand" "r")))
-    (clobber (match_scratch:QI 1 "=X"))]
-   ""
-   "cp __zero_reg__,%A0
-@@ -2212,9 +2293,9 @@
- [(set_attr "cc" "compare")
-  (set_attr "length" "2")])
- 
--(define_insn "*negated_tstsi"
-+(define_insn "*negated_tst<ALLS:mode>"
-   [(set (cc0)
--        (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
-+        (compare (neg:ALLS (match_operand:ALLS 0 "register_operand" "r"))
- 		 (const_int 0)))]
-   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
-   "cp __zero_reg__,%A0
-@@ -2224,10 +2305,10 @@
-   [(set_attr "cc" "compare")
-    (set_attr "length" "4")])
- 
--(define_insn "*reversed_tstsi"
-+(define_insn "*reversed_tst<ALLS:mode>"
-   [(set (cc0)
-         (compare (const_int 0)
--		 (match_operand:SI 0 "register_operand" "r")))
-+		 (match_operand:ALLS 0 "register_operand" "r")))
-    (clobber (match_scratch:QI 1 "=X"))]
-   ""
-   "cp __zero_reg__,%A0
-@@ -2238,10 +2319,10 @@
-    (set_attr "length" "4")])
- 
- 
--(define_insn "*cmpqi"
-+(define_insn "*cmp<ALLQ:mode>"
-   [(set (cc0)
--        (compare (match_operand:QI 0 "register_operand"  "r,r,d")
--		 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
-+        (compare (match_operand:ALLQ 0 "register_operand"  "r,r,d")
-+		 (match_operand:ALLQ 1 "nonmemory_operand" "L,r,i")))]
-   ""
-   "@
- 	tst %0
-@@ -2260,10 +2341,10 @@
-   [(set_attr "cc" "compare")
-    (set_attr "length" "1")])
- 
--(define_insn "*cmphi"
-+(define_insn "*cmp<ALLH:mode>"
-   [(set (cc0)
--	(compare (match_operand:HI 0 "register_operand"  "!w,r,r,d,d,r,r")
--		 (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
-+	(compare (match_operand:ALLH 0 "register_operand"  "!w,r,r,d,d,r,r")
-+		 (match_operand:ALLH 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
-    (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
-   ""
-   "*{
-@@ -2308,10 +2389,10 @@
-    (set_attr "length" "1,2,2,2,3,3,4")])
- 
- 
--(define_insn "*cmpsi"
-+(define_insn "*cmp<ALLS:mode>"
-   [(set (cc0)
--	(compare (match_operand:SI 0 "register_operand"  "r,r,d,d,r,r")
--		 (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
-+	(compare (match_operand:ALLS 0 "register_operand"  "r,r,d,d,r,r")
-+		 (match_operand:ALLS 1 "nonmemory_operand" "L,r,M,i,M,i")))
-    (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
-   ""
-   "*{
-diff -Naurp gcc/config/avr/avr-modes.def gcc/config/avr/avr-modes.def
---- gcc/config/avr/avr-modes.def	1970-01-01 05:30:00.000000000 +0530
-+++ gcc/config/avr/avr-modes.def	2011-10-27 16:55:55.000000000 +0530
-@@ -0,0 +1,34 @@
-+/* Definitions of target machine for GCC for AVR.
-+   Copyright (C) 2009 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 3, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING3.  If not see
-+<http://www.gnu.org/licenses/>.  */
-+
-+/* On 8 bit machines it requires fewer instructions for fixed point
-+   routines if the decimal place is on a byte boundary which is not
-+   the default for signed accum types.  */
-+
-+ADJUST_IBIT (HA, 7);
-+ADJUST_FBIT (HA, 8);
-+
-+ADJUST_IBIT (SA, 15);
-+ADJUST_FBIT (SA, 16);
-+
-+ADJUST_IBIT (DA, 31);
-+ADJUST_FBIT (DA, 32);
-+
-+ADJUST_IBIT (TA, 63);
-+ADJUST_FBIT (TA, 64);
-diff -Naurp gcc/config/avr/avr-protos.h gcc/config/avr/avr-protos.h
---- gcc/config/avr/avr-protos.h	2011-10-27 16:45:17.000000000 +0530
-+++ gcc/config/avr/avr-protos.h	2011-10-27 16:55:55.000000000 +0530
-@@ -75,6 +75,8 @@ extern const char *lshrhi3_out (rtx insn
- extern const char *lshrsi3_out (rtx insn, rtx operands[], int *len);
- extern bool avr_rotate_bytes (rtx operands[]);
- 
-+extern const char *fract_out (rtx insn, rtx operands[], int intsigned, int *l);
-+
- extern void expand_prologue (void);
- extern void expand_epilogue (void);
- extern int avr_epilogue_uses (int regno);
-diff -Naurp gcc/config/avr/libgcc-fixed.S gcc/config/avr/libgcc-fixed.S
---- gcc/config/avr/libgcc-fixed.S	1970-01-01 05:30:00.000000000 +0530
-+++ gcc/config/avr/libgcc-fixed.S	2011-10-27 16:55:55.000000000 +0530
-@@ -0,0 +1,1123 @@
-+/*  -*- Mode: Asm -*-  */
-+/* Copyright (C) 2009
-+   Free Software Foundation, Inc.
-+   Contributed by Sean D'Epagnier
-+
-+This file is free software; you can redistribute it and/or modify it
-+under the terms of the GNU General Public License as published by the
-+Free Software Foundation; either version 3, or (at your option) any
-+later version.
-+
-+In addition to the permissions in the GNU General Public License, the
-+Free Software Foundation gives you unlimited permission to link the
-+compiled version of this file into combinations with other programs,
-+and to distribute those combinations without any restriction coming
-+from the use of this file.  (The General Public License restrictions
-+do apply in other respects; for example, they cover modification of
-+the file, and distribution when not linked into a combine
-+executable.)
-+
-+This file is distributed in the hope that it will be useful, but
-+WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; see the file COPYING.  If not, write to
-+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-+Boston, MA 02110-1301, USA.  */
-+
-+/* Fixed point library routines for avr.  */
-+
-+#define __zero_reg__ r1
-+#define __tmp_reg__ r0
-+#define __SREG__ 0x3f
-+#define __SP_H__ 0x3e
-+#define __SP_L__ 0x3d
-+#define __RAMPZ__ 0x3B
-+
-+/* Conversions to float.  */
-+#if defined (L_fractqqsf)
-+        .global __fractqqsf
-+        .func __fractqqsf
-+__fractqqsf:
-+        clr     r25
-+        sbrc    r24, 7          ; if negative
-+        ser     r25             ; sign extend
-+        mov     r23, r24        ; move in place
-+        mov     r24, r25        ; sign extend lower byte
-+        lsl     r23
-+        clr     r22
-+        rjmp __fractsasf        ; call larger conversion
-+.endfunc
-+#endif  /* defined (L_fractqqsf) */
-+
-+#if defined (L_fractuqqsf)        
-+        .global __fractuqqsf
-+        .func __fractuqqsf
-+__fractuqqsf:
-+        clr     r22
-+        mov     r23, r24
-+        clr     r24
-+        clr     r25
-+        rjmp __fractsasf        ; call larger conversion
-+.endfunc
-+#endif  /* defined (L_fractuqqsf) */
-+        
-+#if defined (L_fracthqsf)        
-+        .global __fracthqsf
-+        .func __fracthqsf
-+__fracthqsf:
-+        mov_l	r22, r24        ; put fractional part in place
-+	mov_h	r23, r25
-+        clr     r25
-+        sbrc    r23, 7          ; if negative
-+        ser     r25             ; sign extend
-+        mov     r24, r25        ; sign extend lower byte
-+        lsl     r22
-+        rol     r23
-+        rjmp    __fractsasf        ; call larger conversion
-+.endfunc
-+#endif  /* defined (L_fracthqsf) */
-+
-+#if defined (L_fractuhqsf)        
-+        .global __fractuhqsf
-+        .func __fractuhqsf
-+__fractuhqsf:
-+        mov_l	r22, r24        ; put fractional part in place
-+	mov_h	r23, r25
-+        clr     r24
-+        clr     r25
-+        rjmp __fractsasf        ; call larger conversion
-+.endfunc
-+#endif  /* defined (L_fractuhqsf) */
-+
-+#if defined (L_fracthasf)        
-+        .global __fracthasf
-+        .func __fracthasf
-+__fracthasf:
-+        clr     r22
-+        mov     r23, r24        ; move into place
-+        mov     r24, r25
-+        clr     r25
-+        sbrc    r24, 7          ; if negative
-+        ser     r25             ; sign extend
-+        rjmp __fractsasf        ; call larger conversion
-+#endif  /* defined (L_fracthasf) */
-+
-+#if defined (L_fractuhasf)        
-+        .global __fractuhasf
-+        .func __fractuhasf
-+__fractuhasf:
-+        clr     r22
-+        mov     r23, r24        ; move into place
-+        rjmp __fractsasf        ; call larger conversion
-+.endfunc
-+#endif  /* defined (L_fractuhasf) */
-+
-+#if defined (L_fractsasf)        
-+        .global __fractsasf
-+        .func __fractsasf
-+__fractsasf:
-+        rcall __floatsisf
-+        tst     r25
-+        breq __fractsasf_exit   ; skip if zero
-+        subi r25, 0x08          ; adjust exponent
-+__fractsasf_exit:
-+        ret
-+.endfunc
-+#endif  /* defined (L_fractsasf) */
-+
-+#if defined (L_fractusasf)        
-+        .global __fractusasf
-+        .func __fractusasf
-+__fractusasf:
-+        rcall   __floatunsisf
-+        tst     r25
-+        breq    __fractusasf_exit  ; skip if zero
-+        subi    r25, 0x08         ; adjust exponent
-+__fractusasf_exit:
-+        ret
-+.endfunc
-+#endif  /* defined (L_fractusasf) */
-+
-+#if defined (L_fractsfqq)        /* Conversions from float.  */
-+        .global __fractsfqq
-+        .func __fractsfqq
-+__fractsfqq:
-+        subi    r25, -11        ; adjust exponent
-+        subi    r24, 128
-+        rjmp    __fixsfsi
-+.endfunc
-+#endif  /* defined (L_fractqq) */
-+
-+#if defined (L_fractsfuqq)        
-+        .global __fractsfuqq
-+        .func __fractsfuqq
-+__fractsfuqq:
-+        subi    r25, -12        ; adjust exponent
-+        rjmp    __fixsfsi
-+.endfunc
-+#endif  /* defined (L_fractuqq) */
-+
-+#if defined (L_fractsfhq)        
-+        .global __fractsfhq
-+        .func __fractsfhq
-+__fractsfhq:
-+        subi    r25, -15        ; adjust exponent
-+        subi    r24, 128
-+        rjmp    __fixsfsi
-+.endfunc
-+#endif  /* defined (L_fractsfhq) */
-+
-+#if defined (L_fractsfuhq)        
-+        .global __fractsfuhq
-+        .func __fractsfuhq
-+__fractsfuhq:
-+        subi    r25, -16        ; adjust exponent
-+        rjmp    __fixsfsi
-+.endfunc
-+#endif  /* defined (L_fractsfuhq) */
-+
-+#if defined (L_fractsfha)
-+        .global __fractsfha
-+        .func __fractsfha
-+__fractsfha:
-+.endfunc
-+        .global __fractsfuha
-+        .func __fractsfuha
-+__fractsfuha:
-+        subi    r25, -12        ; adjust exponent
-+        rjmp    __fixsfsi
-+.endfunc
-+#endif  /* defined (L_fractsfha) */
-+
-+#if defined (L_fractsfsa)
-+        .global __fractsfsa
-+        .func __fractsfsa
-+__fractsfsa:
-+.endfunc
-+        .global __fractsfusa
-+        .func __fractsfusa
-+__fractsfusa:
-+        subi    r25, -8        ; adjust exponent
-+        rjmp    __fixsfsi
-+.endfunc
-+#endif  /* defined (L_fractsfsa) */
-+
-+/* For multiplication the functions here are called directly from
-+   avr-fixed.md patterns, instead of using the standard libcall mechanisms.
-+   This can make better code because GCC knows exactly which
-+   of the call-used registers (not all of them) are clobbered.  */
-+        
-+/* mulqq and muluqq open coded on the enhanced core */
-+#if !defined (__AVR_HAVE_MUL__)
-+/*******************************************************
-+        Fractional Multiplication  8 x 8
-+*******************************************************/
-+#define	r_arg2	r22		/* multiplicand */
-+#define	r_arg1 	r24		/* multiplier */
-+#define r_res	__tmp_reg__	/* result */
-+
-+#if defined (L_mulqq3)        
-+	.global	__mulqq3
-+       	.func	__mulqq3
-+__mulqq3:
-+        mov     r_res, r_arg1
-+        eor     r_res, r_arg2
-+        bst     r_res, 7
-+        lsl     r_arg1             
-+        lsl     r_arg2
-+        brcc    __mulqq3_skipneg
-+        neg     r_arg2
-+__mulqq3_skipneg: 
-+        rcall   __muluqq3
-+        lsr     r_arg1
-+        brtc    __mulqq3_exit
-+        neg     r_arg1
-+__mulqq3_exit:
-+        ret
-+
-+.endfunc
-+#endif  /* defined (L_mulqq3) */
-+
-+#if defined (L_muluqq3)        
-+	.global	__muluqq3
-+	.func	__muluqq3
-+__muluqq3:
-+	clr	r_res		; clear result
-+__muluqq3_loop:
-+	lsr	r_arg2          ; shift multiplicand
-+	sbrc	r_arg1,7
-+	add	r_res,r_arg2
-+	breq	__muluqq3_exit	; while multiplicand != 0
-+	lsl	r_arg1
-+	brne	__muluqq3_loop	; exit if multiplier = 0
-+__muluqq3_exit:
-+	mov	r_arg1,r_res	; result to return register
-+	ret
-+#undef r_arg2  
-+#undef r_arg1  
-+#undef r_res   
-+	
-+.endfunc
-+#endif  /* defined (L_muluqq3) */
-+#endif /* !defined (__AVR_HAVE_MUL__) */
-+
-+/*******************************************************
-+        Fractional  Multiplication  16 x 16
-+*******************************************************/
-+
-+#if defined (__AVR_HAVE_MUL__)
-+#define	r_arg1L	r22		/* multiplier Low */
-+#define	r_arg1H	r23		/* multiplier High */
-+#define	r_arg2L	r20		/* multiplicand Low */
-+#define	r_arg2H	r21		/* multiplicand High */
-+#define r_resL	r18     	/* result Low */
-+#define r_resH  r19	        /* result High */
-+
-+#if defined (L_mulhq3)
-+      	.global	__mulhq3
-+	.func	__mulhq3
-+__mulhq3:
-+        fmuls   r_arg1H, r_arg2H
-+        movw    r_resL, r0
-+        fmulsu  r_arg2H, r_arg1L
-+        clr     r_arg1L
-+        sbc     r_resH, r_arg1L
-+        add     r_resL, r1
-+        adc     r_resH, r_arg1L
-+        fmulsu  r_arg1H, r_arg2L
-+        sbc     r_resH, r_arg1L
-+        add     r_resL, r1
-+        adc     r_resH, r_arg1L
-+        clr     __zero_reg__
-+        ret
-+.endfunc
-+#endif  /* defined (L_mulhq3) */
-+
-+#if defined (L_muluhq3)        
-+	.global	__muluhq3
-+	.func	__muluhq3
-+__muluhq3:
-+        mul     r_arg1H, r_arg2H
-+        movw    r_resL, r0
-+        mul     r_arg1H, r_arg2L
-+        add     r_resL, r1
-+        clr     __zero_reg__
-+        adc     r_resH, __zero_reg__
-+        mul     r_arg1L, r_arg2H
-+        add     r_resL, r1
-+        clr     __zero_reg__
-+        adc     r_resH, __zero_reg__
-+        ret
-+.endfunc
-+#endif  /* defined (L_muluhq3) */
-+
-+#else
-+#define	r_arg1L	r24		/* multiplier Low */
-+#define	r_arg1H	r25		/* multiplier High */
-+#define	r_arg2L	r22		/* multiplicand Low */
-+#define	r_arg2H	r23		/* multiplicand High */
-+#define r_resL	__tmp_reg__	/* result Low */
-+#define r_resH  __zero_reg__	/* result High */
-+
-+#if defined (L_mulhq3)        
-+      	.global	__mulhq3
-+	.func	__mulhq3
-+__mulhq3:
-+        mov     r_resL, r_arg1H
-+        eor     r_resL, r_arg2H
-+        bst     r_resL, 7
-+        lsl     r_arg1L
-+        rol     r_arg1H
-+        lsl     r_arg2L
-+        rol     r_arg2H
-+        brcc    mulhq3_skipneg
-+        com     r_arg2H
-+        neg     r_arg2L
-+        sbci    r_arg2H, -1
-+mulhq3_skipneg:
-+        rcall   __muluhq3
-+        lsr     r_arg1H
-+        ror     r_arg1L
-+        brtc    mulhq3_exit
-+        com     r_arg1H
-+        neg     r_arg1L
-+        sbci    r_arg1H, -1
-+mulhq3_exit:
-+        ret
-+.endfunc
-+#endif  /* defined (L_mulhq3) */
-+
-+#if defined (L_muluhq3)
-+	.global	__muluhq3
-+	.func	__muluhq3
-+__muluhq3:
-+	clr	r_resL		; clear result
-+__muluhq3_loop:
-+	lsr	r_arg2H		; shift multiplicand
-+	ror	r_arg2L
-+        sbrs	r_arg1H,7
-+	rjmp	__muluhq3_skip
-+	add	r_resL,r_arg2L	; result + multiplicand
-+	adc	r_resH,r_arg2H
-+__muluhq3_skip:	
-+	lsl	r_arg1L 	; shift multiplier
-+	rol	r_arg1H
-+        brne    __muluhq3_loop
-+        cpi     r_arg1L, 0
-+        brne    __muluhq3_loop   ; exit multiplier = 0
-+	mov_l	r_arg1L,r_resL
-+	mov_h	r_arg1H,r_resH	; result to return register
-+        clr     __zero_reg__    ; zero the zero reg
-+	ret
-+.endfunc
-+#endif  /* defined (L_muluhq3) */
-+
-+#endif /* defined (__AVR_HAVE_MUL__) */
-+
-+#undef r_arg1L
-+#undef r_arg1H
-+#undef r_arg2L
-+#undef r_arg2H
-+#undef r_resL 	
-+#undef r_resH 
-+
-+/*******************************************************
-+        Fixed  Multiplication  8.8 x 8.8
-+*******************************************************/
-+
-+#if defined (__AVR_HAVE_MUL__)
-+#define	r_arg1L	r22		/* multiplier Low */
-+#define	r_arg1H	r23		/* multiplier High */
-+#define	r_arg2L	r20		/* multiplicand Low */
-+#define	r_arg2H	r21		/* multiplicand High */
-+#define r_resL	r18     	/* result Low */
-+#define r_resH  r19	        /* result High */
-+
-+#if defined (L_mulha3)
-+	.global	__mulha3
-+	.func	__mulha3
-+__mulha3:
-+        mul     r_arg1L, r_arg2L
-+        mov     r_resL, r1
-+        muls    r_arg1H, r_arg2H
-+        mov     r_resH, r0
-+        mulsu   r_arg1H, r_arg2L
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        mulsu   r_arg2H, r_arg1L
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        clr     __zero_reg__
-+        ret
-+.endfunc
-+#endif  /* defined (L_mulha3) */
-+
-+#if defined (L_muluha3)        
-+	.global	__muluha3
-+	.func	__muluha3
-+__muluha3:
-+        mul     r_arg1L, r_arg2L
-+        mov     r_resL, r1
-+        mul     r_arg1H, r_arg2H
-+        mov     r_resH, r0
-+        mul     r_arg1H, r_arg2L
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        mul     r_arg1L, r_arg2H
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        clr     __zero_reg__
-+        ret
-+.endfunc
-+#endif  /* defined (L_muluha3) */
-+
-+#else
-+
-+#define	r_arg1L	r24		/* multiplier Low */
-+#define	r_arg1H	r25		/* multiplier High */
-+#define	r_arg2L	r22		/* multiplicand Low */
-+#define	r_arg2H	r23		/* multiplicand High */
-+#define r_resL	r18     	/* result Low */
-+#define r_resH  r19	        /* result High */
-+#define r_scratchL  r0     	/* scratch Low */
-+#define r_scratchH  r1
-+
-+#if defined (L_mulha3)
-+       	.global	__mulha3
-+	.func	__mulha3
-+__mulha3:
-+        mov     r_resL, r_arg1H
-+        eor     r_resL, r_arg2H
-+        bst     r_resL, 7
-+        sbrs    r_arg1H, 7
-+        rjmp    __mulha3_arg1pos
-+        com     r_arg1H
-+        neg     r_arg1L
-+        sbci    r_arg1H,-1
-+__mulha3_arg1pos:
-+        sbrs    r_arg2H, 7
-+        rjmp    __mulha3_arg2pos
-+        com     r_arg2H
-+        neg     r_arg2L
-+        sbci    r_arg2H,-1
-+__mulha3_arg2pos:
-+        rcall   __muluha3
-+        brtc    __mulha3_exit
-+        com     r_resH
-+        neg     r_resL
-+        sbci    r_resH,-1
-+__mulha3_exit:
-+        ret
-+.endfunc        
-+#endif 	/* defined (L_mulha3) */
-+
-+#if defined (L_muluha3)        
-+       	.global	__muluha3
-+	.func	__muluha3
-+__muluha3:
-+	clr	r_resL		; clear result
-+        clr     r_resH
-+        mov_l   r0, r_arg1L     ; save multiplicand
-+        mov_h   r1, r_arg1H
-+__muluha3_loop1:
-+        sbrs	r_arg2H,0
-+	rjmp	__muluha3_skip1
-+	add	r_resL,r_arg1L	; result + multiplicand
-+	adc	r_resH,r_arg1H
-+__muluha3_skip1:
-+	lsl	r_arg1L		; shift multiplicand
-+	rol	r_arg1H
-+        sbiw    r_arg1L,0
-+        breq    __muluha3_loop1_done ; exit multiplicand = 0
-+        lsr     r_arg2H
-+        brne    __muluha3_loop1 ; exit multiplier = 0
-+__muluha3_loop1_done:
-+        mov_l   r_arg1L, r_scratchL     ; restore multiplicand
-+        mov_h   r_arg1H, r_scratchH
-+__muluha3_loop2:
-+	lsr	r_arg1H		; shift multiplicand
-+	ror	r_arg1L
-+        sbiw    r_arg1L,0
-+        breq    __muluha3_exit  ; exit if multiplicand = 0
-+        sbrs    r_arg2L,7
-+        rjmp    __muluha3_skip2
-+	add	r_resL,r_arg1L	; result + multiplicand
-+	adc	r_resH,r_arg1H
-+__muluha3_skip2:
-+        lsl     r_arg2L
-+        brne    __muluha3_loop2 ; exit if multiplier = 0
-+__muluha3_exit:
-+        clr     __zero_reg__    ; got clobbered
-+        ret
-+.endfunc        
-+#endif  /* defined (L_muluha3) */
-+
-+#endif /* defined (__AVR_HAVE_MUL__) */
-+
-+#undef r_arg1L
-+#undef r_arg1H
-+#undef r_arg2L
-+#undef r_arg2H
-+#undef r_resL 	
-+#undef r_resH 
-+
-+/*******************************************************
-+        Fixed  Multiplication  16.16 x 16.16
-+*******************************************************/
-+
-+#if defined (__AVR_HAVE_MUL__)
-+/* uses nonstandard registers because mulus only works from 16-23 */
-+#define r_clr    r15
-+
-+#define	r_arg1L  r16		/* multiplier Low */
-+#define	r_arg1H  r17
-+#define	r_arg1HL r18
-+#define	r_arg1HH r19		/* multiplier High */
-+
-+#define	r_arg2L  r20		/* multiplicand Low */
-+#define	r_arg2H	 r21
-+#define	r_arg2HL r22
-+#define	r_arg2HH r23		/* multiplicand High */
-+
-+#define r_resL	 r24     	/* result Low */
-+#define r_resH   r25
-+#define r_resHL	 r26
-+#define r_resHH  r27	        /* result High */
-+
-+#if defined (L_mulsa3)        
-+	.global	__mulsa3
-+	.func	__mulsa3
-+__mulsa3:
-+        clr     r_clr
-+        clr     r_resH
-+        clr     r_resHL
-+        clr     r_resHH        
-+        mul     r_arg1H, r_arg2L
-+        mov     r_resL, r1
-+        mul     r_arg1L, r_arg2H
-+        add     r_resL, r1
-+        adc     r_resH, r_clr
-+        mul     r_arg1L, r_arg2HL
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        adc     r_resHL, r_clr
-+        mul     r_arg1H, r_arg2H
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        adc     r_resHL, r_clr
-+        mul     r_arg1HL, r_arg2L
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        adc     r_resHL, r_clr
-+        mulsu   r_arg2HH, r_arg1L
-+        sbc     r_resHH, r_clr
-+        add     r_resH, r0
-+        adc     r_resHL, r1
-+        adc     r_resHH, r_clr
-+        mul     r_arg1H, r_arg2HL
-+        add     r_resH, r0
-+        adc     r_resHL, r1
-+        adc     r_resHH, r_clr
-+        mul     r_arg1HL, r_arg2H
-+        add     r_resH, r0
-+        adc     r_resHL, r1
-+        adc     r_resHH, r_clr
-+        mulsu   r_arg1HH, r_arg2L
-+        sbc     r_resHH, r_clr        
-+        add     r_resH, r0
-+        adc     r_resHL, r1
-+        adc     r_resHH, r_clr
-+        mulsu   r_arg2HH, r_arg1H
-+        add     r_resHL, r0
-+        adc     r_resHH, r1
-+        mul     r_arg1HL, r_arg2HL
-+        add     r_resHL, r0
-+        adc     r_resHH, r1
-+        mulsu   r_arg1HH, r_arg2H
-+        add     r_resHL, r0
-+        adc     r_resHH, r1
-+        mulsu   r_arg2HH, r_arg1HL
-+        add     r_resHH, r0
-+        mulsu   r_arg1HH, r_arg2HL
-+        add     r_resHH, r0
-+        clr     __zero_reg__
-+        ret
-+.endfunc
-+#endif
-+
-+#if defined (L_mulusa3)        
-+	.global	__mulusa3
-+	.func	__mulusa3
-+__mulusa3:
-+        clr     r_clr
-+        clr     r_resH
-+        clr     r_resHL
-+        clr     r_resHH        
-+        mul     r_arg1H, r_arg2L
-+        mov     r_resL, r1
-+        mul     r_arg1L, r_arg2H
-+        add     r_resL, r1
-+        adc     r_resH, r_clr
-+        mul     r_arg1L, r_arg2HL
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        adc     r_resHL, r_clr
-+        mul     r_arg1H, r_arg2H
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        adc     r_resHL, r_clr
-+        mul     r_arg1HL, r_arg2L
-+        add     r_resL, r0
-+        adc     r_resH, r1
-+        adc     r_resHL, r_clr
-+        mul     r_arg1L, r_arg2HH
-+        add     r_resH, r0
-+        adc     r_resHL, r1
-+        adc     r_resHH, r_clr
-+        mul     r_arg1H, r_arg2HL
-+        add     r_resH, r0
-+        adc     r_resHL, r1
-+        adc     r_resHH, r_clr
-+        mul     r_arg1HL, r_arg2H
-+        add     r_resH, r0
-+        adc     r_resHL, r1
-+        adc     r_resHH, r_clr
-+        mul     r_arg1HH, r_arg2L
-+        add     r_resH, r0
-+        adc     r_resHL, r1
-+        adc     r_resHH, r_clr
-+        mul     r_arg1H, r_arg2HH
-+        add     r_resHL, r0
-+        adc     r_resHH, r1
-+        mul     r_arg1HL, r_arg2HL
-+        add     r_resHL, r0
-+        adc     r_resHH, r1
-+        mul     r_arg1HH, r_arg2H
-+        add     r_resHL, r0
-+        adc     r_resHH, r1
-+        mul     r_arg1HL, r_arg2HH
-+        add     r_resHH, r0
-+        mul     r_arg1HH, r_arg2HL
-+        add     r_resHH, r0
-+        clr     __zero_reg__
-+        ret
-+.endfunc
-+#endif
-+
-+#else
-+
-+#define	r_arg1L  r18		/* multiplier Low */
-+#define	r_arg1H  r19
-+#define	r_arg1HL r20
-+#define	r_arg1HH r21		/* multiplier High */
-+
-+/* these registers needed for sbiw */
-+#define	r_arg2L	 r24		/* multiplicand Low */
-+#define	r_arg2H	 r25
-+#define	r_arg2HL r26
-+#define	r_arg2HH r27		/* multiplicand High */
-+
-+#define r_resL	 r14     	/* result Low */
-+#define r_resH   r15
-+#define r_resHL	 r16
-+#define r_resHH  r17	        /* result High */
-+
-+#define r_scratchL  r0     	/* scratch Low */
-+#define r_scratchH  r1
-+#define r_scratchHL r22
-+#define r_scratchHH r23	        /* scratch High */
-+
-+#if defined (L_mulsa3)
-+       	.global	__mulsa3
-+	.func	__mulsa3
-+__mulsa3:
-+        mov     r_resL, r_arg1HH
-+        eor     r_resL, r_arg2HH
-+        bst     r_resL, 7
-+        sbrs    r_arg1HH, 7
-+        rjmp    __mulsa3_arg1pos
-+        com     r_arg1HH
-+        com     r_arg1HL
-+        com     r_arg1H
-+        neg     r_arg1L
-+        sbci    r_arg1H,-1
-+        sbci    r_arg1HL,-1        
-+        sbci    r_arg1HH,-1
-+__mulsa3_arg1pos:
-+        sbrs    r_arg2HH, 7
-+        rjmp    __mulsa3_arg2pos
-+        com     r_arg2HH
-+        com     r_arg2HL       
-+        com     r_arg2H
-+        neg     r_arg2L
-+        sbci    r_arg2H,-1
-+        sbci    r_arg2HL,-1
-+        sbci    r_arg2HH,-1        
-+__mulsa3_arg2pos:
-+        rcall   __mulusa3
-+        brtc    __mulsa3_exit
-+        com     r_resHH
-+        com     r_resHL
-+        com     r_resH
-+        com     r_resL
-+        adc	r_resL,__zero_reg__
-+        adc	r_resH,__zero_reg__
-+        adc     r_resHL,__zero_reg__
-+        adc     r_resHH,__zero_reg__
-+__mulsa3_exit:
-+        ret
-+.endfunc        
-+#endif  /* defined (L_mulsa3) */
-+
-+#if defined (L_mulusa3)
-+       	.global	__mulusa3
-+	.func	__mulusa3
-+__mulusa3:
-+	clr	r_resL		; clear result
-+        clr     r_resH
-+        mov_l   r_resHL, r_resL
-+        mov_h   r_resHH, r_resH
-+        mov_l   r_scratchL, r_arg1L     ; save multiplicand
-+        mov_h   r_scratchH, r_arg1H
-+        mov_l   r_scratchHL, r_arg1HL
-+        mov_h   r_scratchHH, r_arg1HH
-+__mulusa3_loop1:
-+        sbrs	r_arg2HL,0
-+	rjmp	__mulusa3_skip1
-+	add	r_resL,r_arg1L	; result + multiplicand
-+	adc	r_resH,r_arg1H
-+	adc	r_resHL,r_arg1HL
-+	adc	r_resHH,r_arg1HH
-+__mulusa3_skip1:
-+	lsl	r_arg1L		; shift multiplicand
-+	rol	r_arg1H
-+	rol	r_arg1HL
-+	rol	r_arg1HH
-+        lsr     r_arg2HH
-+        ror     r_arg2HL
-+        sbiw    r_arg2HL,0
-+        brne    __mulusa3_loop1 ; exit multiplier = 0
-+__mulusa3_loop1_done:
-+        mov_l   r_arg1L, r_scratchL     ; restore multiplicand
-+        mov_h   r_arg1H, r_scratchH
-+        mov_l   r_arg1HL, r_scratchHL
-+        mov_h   r_arg1HH, r_scratchHH
-+__mulusa3_loop2:
-+	lsr	r_arg1HH		; shift multiplicand
-+	ror	r_arg1HL
-+        ror     r_arg1H
-+        ror     r_arg1L
-+        sbrs    r_arg2H,7
-+        rjmp    __mulusa3_skip2
-+	add	r_resL,r_arg1L	; result + multiplicand
-+	adc	r_resH,r_arg1H
-+	adc	r_resHL,r_arg1HL
-+	adc	r_resHH,r_arg1HH
-+__mulusa3_skip2:
-+        lsl     r_arg2L
-+        rol     r_arg2H
-+        sbiw    r_arg2L,0
-+        brne    __mulusa3_loop2 ; exit if multiplier = 0
-+__mulusa3_exit:
-+        clr     __zero_reg__    ; got clobbered
-+        ret
-+.endfunc        
-+#endif  /* defined (L_mulusa3) */
-+
-+#undef r_scratchL
-+#undef r_scratchH
-+#undef r_scratchHL
-+#undef r_scratchHH
-+        
-+#endif
-+
-+#undef	r_arg1L
-+#undef	r_arg1H
-+#undef	r_arg1HL
-+#undef	r_arg1HH
-+
-+#undef	r_arg2L
-+#undef	r_arg2H
-+#undef	r_arg2HL
-+#undef	r_arg2HH
-+
-+#undef r_resL
-+#undef r_resH
-+#undef r_resHL
-+#undef r_resHH
-+
-+/*******************************************************
-+              Fractional Division 8 / 8
-+*******************************************************/
-+#define	r_divd	r25	/* dividend */
-+#define	r_quo	r24	/* quotient */
-+#define	r_div	r22	/* divisor */
-+#define	r_cnt	r23	/* loop count */
-+
-+#if defined (L_divqq3)
-+	.global	__divqq3
-+	.func	__divqq3
-+__divqq3:
-+        mov     r0, r_divd
-+        eor     r0, r_div
-+        sbrc    r_div, 7
-+        neg     r_div          
-+        sbrc    r_divd, 7
-+        neg     r_divd          
-+        cp      r_divd, r_div
-+        breq    __divqq3_minus1  ; if equal return -1
-+        rcall   __udivuqq3
-+        lsr     r_quo
-+        sbrc    r0, 7   ; negate result if needed
-+        neg     r_quo
-+        ret
-+__divqq3_minus1:
-+        ldi     r_quo, 0x80
-+        ret
-+.endfunc
-+#endif 	/* defined (L_divqq3) */
-+
-+#if defined (L_udivuqq3)
-+	.global	__udivuqq3
-+	.func	__udivuqq3
-+__udivuqq3:
-+	clr	r_quo           ; clear quotient
-+	ldi	r_cnt,8	        ; init loop counter
-+__udivuqq3_loop:
-+	lsl	r_divd		; shift dividend
-+        brcs    __udivuqq3_ep   ; dividend overflow
-+	cp	r_divd,r_div	; compare dividend & divisor
-+	brcc	__udivuqq3_ep	; dividend >= divisor
-+	rol	r_quo		; shift quotient (with CARRY)
-+        rjmp    __udivuqq3_cont
-+__udivuqq3_ep:
-+	sub	r_divd,r_div	; restore dividend
-+	lsl	r_quo		; shift quotient (without CARRY)
-+__udivuqq3_cont:
-+	dec	r_cnt		; decrement loop counter
-+	brne	__udivuqq3_loop
-+	com	r_quo		; complement result 
-+				; because C flag was complemented in loop
-+	ret
-+.endfunc
-+#endif 	/* defined (L_udivuqq3) */
-+
-+#undef	r_divd
-+#undef	r_quo
-+#undef	r_div
-+#undef	r_cnt
-+        
-+
-+/*******************************************************
-+               Fractional Division 16 / 16
-+*******************************************************/
-+#define	r_divdL	r26	/* dividend Low */
-+#define	r_divdH	r27	/* dividend Hig */        
-+#define	r_quoL	r24	/* quotient Low */
-+#define	r_quoH	r25	/* quotient High */        
-+#define	r_divL	r22	/* divisor */
-+#define	r_divH	r23	/* divisor */        
-+#define	r_cnt 21
-+
-+#if defined (L_divhq3)
-+	.global	__divhq3
-+	.func	__divhq3
-+__divhq3:
-+        mov     r0, r_divdH
-+        eor     r0, r_divH
-+        sbrs    r_divH, 7
-+        rjmp    __divhq3_divpos
-+        com     r_divH
-+        neg     r_divL
-+        sbci    r_divH,-1
-+__divhq3_divpos:        
-+        sbrs    r_divdH, 7
-+        rjmp    __divhq3_divdpos
-+        com     r_divdH
-+        neg     r_divdL
-+        sbci    r_divdH,-1
-+__divhq3_divdpos:
-+        cp      r_divdL, r_divL
-+        cpc     r_divdH, r_divH
-+        breq    __divhq3_minus1  ; if equal return -1
-+        rcall   __udivuhq3
-+        lsr     r_quoH
-+        ror     r_quoL
-+        sbrs    r0, 7   ; negate result if needed
-+        ret
-+        com     r_quoH
-+        neg     r_quoL
-+        sbci    r_quoH,-1
-+        ret
-+__divhq3_minus1:
-+        ldi     r_quoH, 0x80
-+        clr     r_quoL
-+        ret
-+.endfunc
-+#endif 	/* defined (L_divhq3) */
-+
-+#if defined (L_udivuhq3)
-+	.global	__udivuhq3
-+	.func	__udivuhq3
-+__udivuhq3:
-+	sub	r_quoH,r_quoH   ; clear quotient and carry
-+        .global	__udivuha3_entry
-+__udivuha3_entry:       
-+	clr	r_quoL          ; clear quotient
-+	ldi	r_cnt,16        ; init loop counter
-+__udivuhq3_loop:
-+        rol     r_divdL		; shift dividend (with CARRY)
-+	rol	r_divdH
-+        brcs    __udivuhq3_ep   ; dividend overflow
-+	cp	r_divdL,r_divL	; compare dividend & divisor        
-+	cpc	r_divdH,r_divH
-+	brcc	__udivuhq3_ep	; dividend >= divisor
-+	rol	r_quoL		; shift quotient (with CARRY)
-+        rjmp    __udivuhq3_cont
-+__udivuhq3_ep:
-+	sub	r_divdL,r_divL	; restore dividend
-+	sbc	r_divdH,r_divH
-+	lsl	r_quoL		; shift quotient (without CARRY)
-+__udivuhq3_cont:
-+        rol     r_quoH          ; shift quotient
-+	dec	r_cnt		; decrement loop counter
-+	brne	__udivuhq3_loop
-+	com	r_quoL		; complement result 
-+        com     r_quoH          ; because C flag was complemented in loop
-+	ret
-+.endfunc
-+#endif 	/* defined (L_udivuhq3) */
-+
-+/*******************************************************
-+               Fixed Division 8.8 / 8.8
-+*******************************************************/
-+#if defined (L_divha3)
-+	.global	__divha3
-+	.func	__divha3
-+__divha3:
-+        mov     r0, r_divdH
-+        eor     r0, r_divH
-+        sbrs    r_divH, 7
-+        rjmp    __divha3_divpos
-+        com     r_divH
-+        neg     r_divL
-+        sbci    r_divH,-1
-+__divha3_divpos:        
-+        sbrs    r_divdH, 7
-+        rjmp    __divha3_divdpos
-+        com     r_divdH
-+        neg     r_divdL
-+        sbci    r_divdH,-1
-+__divha3_divdpos:
-+        rcall   __udivuha3
-+        sbrs    r0, 7   ; negate result if needed
-+        ret
-+        com     r_quoH
-+        neg     r_quoL
-+        sbci    r_quoH,-1
-+        ret
-+.endfunc
-+#endif 	/* defined (L_divha3) */
-+
-+#if defined (L_udivuha3)
-+	.global	__udivuha3
-+	.func	__udivuha3
-+__udivuha3:
-+        mov     r_quoH, r_divdL
-+        mov     r_divdL, r_divdH
-+	clr	r_divdH
-+        lsl     r_quoH           ; shift quotient into carry
-+        rjmp    __udivuha3_entry ; same as fractional after rearrange
-+.endfunc
-+#endif 	/* defined (L_udivuha3) */
-+
-+#undef	r_divdL
-+#undef	r_divdH
-+#undef	r_quoL
-+#undef	r_quoH
-+#undef	r_divL
-+#undef	r_divH
-+#undef	r_cnt
-+
-+/*******************************************************
-+            Fixed Division 16.16 / 16.16
-+*******************************************************/
-+#define r_arg1L  r24    /* arg1 gets passed already in place */
-+#define r_arg1H  r25
-+#define r_arg1HL r26
-+#define r_arg1HH r27        
-+#define	r_divdL  r26	/* dividend Low */
-+#define	r_divdH  r27
-+#define	r_divdHL r30
-+#define	r_divdHH r31	/* dividend High */        
-+#define	r_quoL	 r22	/* quotient Low */
-+#define	r_quoH	 r23
-+#define	r_quoHL	 r24
-+#define	r_quoHH	 r25	/* quotient High */        
-+#define	r_divL	 r18	/* divisor Low */
-+#define	r_divH	 r19
-+#define	r_divHL	 r20
-+#define	r_divHH	 r21	/* divisor High */        
-+#define	r_cnt  __zero_reg__  /* loop count (0 after the loop!) */
-+
-+#if defined (L_divsa3)
-+	.global	__divsa3
-+	.func	__divsa3
-+__divsa3:
-+        mov     r0, r27
-+        eor     r0, r_divHH        
-+        sbrs    r_divHH, 7
-+        rjmp    __divsa3_divpos
-+        com     r_divHH
-+        com     r_divHL
-+        com     r_divH        
-+        neg     r_divL
-+        sbci    r_divH,-1
-+        sbci    r_divHL,-1
-+        sbci    r_divHH,-1        
-+__divsa3_divpos:
-+        sbrs    r_arg1HH, 7
-+        rjmp    __divsa3_arg1pos
-+        com     r_arg1HH
-+        com     r_arg1HL
-+        com     r_arg1H        
-+        neg     r_arg1L
-+        sbci    r_arg1H,-1
-+        sbci    r_arg1HL,-1
-+        sbci    r_arg1HH,-1        
-+__divsa3_arg1pos:
-+        rcall   __udivusa3        
-+        sbrs    r0, 7   ; negate result if needed
-+        ret
-+        com     r_quoHH
-+        com     r_quoHL
-+        com     r_quoH        
-+        neg     r_quoL
-+        sbci    r_quoH,-1
-+        sbci    r_quoHL,-1
-+        sbci    r_quoHH,-1        
-+        ret
-+.endfunc
-+#endif 	/* defined (L_divsa3) */
-+
-+#if defined (L_udivusa3)
-+	.global	__udivusa3
-+	.func	__udivusa3
-+__udivusa3:
-+        ldi     r_divdHL, 32        ; init loop counter
-+        mov     r_cnt, r_divdHL
-+	clr	r_divdHL
-+	clr	r_divdHH        
-+	mov_l	r_quoL, r_divdHL
-+	mov_h	r_quoH, r_divdHH
-+	lsl     r_quoHL         ; shift quotient into carry
-+	rol     r_quoHH
-+__udivusa3_loop:
-+        rol     r_divdL 	; shift dividend (with CARRY)
-+	rol	r_divdH
-+	rol	r_divdHL
-+	rol	r_divdHH
-+        brcs    __udivusa3_ep   ; dividend overflow
-+	cp	r_divdL,r_divL	; compare dividend & divisor        
-+	cpc	r_divdH,r_divH
-+	cpc	r_divdHL,r_divHL
-+	cpc	r_divdHH,r_divHH
-+	brcc	__udivusa3_ep	; dividend >= divisor
-+	rol	r_quoL		; shift quotient (with CARRY)
-+        rjmp    __udivusa3_cont
-+__udivusa3_ep:
-+	sub	r_divdL,r_divL	; restore dividend
-+	sbc	r_divdH,r_divH
-+	sbc	r_divdHL,r_divHL
-+	sbc	r_divdHH,r_divHH
-+	lsl	r_quoL		; shift quotient (without CARRY)
-+__udivusa3_cont:
-+        rol     r_quoH          ; shift quotient
-+        rol     r_quoHL
-+        rol     r_quoHH
-+	dec	r_cnt		; decrement loop counter
-+	brne	__udivusa3_loop
-+	com	r_quoL		; complement result 
-+        com     r_quoH          ; because C flag was complemented in loop
-+	com	r_quoHL
-+        com     r_quoHH
-+	ret
-+.endfunc
-+#endif 	/* defined (L_udivusa3) */
-+
-+#undef	r_divdL
-+#undef	r_divdH
-+#undef	r_divdHL
-+#undef	r_divdHH
-+#undef	r_quoL
-+#undef	r_quoH
-+#undef	r_quoHL
-+#undef	r_quoHH
-+#undef	r_divL
-+#undef	r_divH
-+#undef	r_divHL
-+#undef	r_divHH
-+#undef	r_cnt
-diff -Naurp gcc/config/avr/libgcc.S gcc/config/avr/libgcc.S
---- gcc/config/avr/libgcc.S	2011-10-27 16:45:17.000000000 +0530
-+++ gcc/config/avr/libgcc.S	2011-10-27 16:55:55.000000000 +0530
-@@ -163,6 +163,23 @@ __mulhi3_exit:
- 	.global	__mulhisi3
- 	.func	__mulhisi3
- __mulhisi3:
-+#if defined (__AVR_HAVE_MUL__)
-+	muls	r21, r19
-+	movw	r24, r0
-+	mul	r20, r18
-+	movw	r22, r0
-+	mulsu	r21, r18
-+	add	r23, r0
-+	adc	r24, r1
-+	clr	r1
-+	adc	r25, r1
-+	mulsu	r19, r20
-+	add	r23, r0
-+	adc	r24, r1
-+	clr	r1
-+	adc	r25, r1
-+	ret
-+#else
- 	mov_l	r18, r24
- 	mov_h	r19, r25
- 	clr	r24
-@@ -174,6 +191,7 @@ __mulhisi3:
- 	dec	r20
- 	mov	r21, r20
- 	rjmp	__mulsi3
-+#endif /* defined (__AVR_HAVE_MUL__) */
- 	.endfunc
- #endif /* defined (L_mulhisi3) */
- 
-@@ -181,13 +199,31 @@ __mulhisi3:
- 	.global	__umulhisi3
- 	.func	__umulhisi3
- __umulhisi3:
--	mov_l	r18, r24
--	mov_h	r19, r25
-+#if defined (__AVR_HAVE_MUL__)
-+	mul	r21, r19
-+	movw	r24, r0
-+	mul	r20, r18
-+	movw	r22, r0
-+	mul	r21, r18
-+	add	r23, r0
-+	adc	r24, r1
-+	clr	r1
-+	adc	r25, r1
-+	mul	r19, r20
-+	add	r23, r0
-+	adc	r24, r1
-+	clr	r1
-+	adc	r25, r1
-+	ret
-+#else
-+	mov_l	r22, r20
-+	mov_h	r23, r21
- 	clr	r24
- 	clr	r25
- 	clr	r20
- 	clr	r21
- 	rjmp	__mulsi3
-+#endif
- 	.endfunc
- #endif /* defined (L_umulhisi3) */
- 
-@@ -200,7 +236,6 @@ __umulhisi3:
- #define	r_arg1HL r24
- #define	r_arg1HH r25		/* multiplier High */
- 
--
- #define	r_arg2L  r18		/* multiplicand Low */
- #define	r_arg2H  r19	
- #define	r_arg2HL r20
-@@ -556,6 +591,23 @@ __divmodsi4_neg1:
- 	.endfunc
- #endif /* defined (L_divmodsi4) */
- 
-+#undef	r_remHH
-+#undef	r_remHL
-+#undef	r_remH
-+#undef	r_remL
-+
-+#undef	r_arg1HH
-+#undef	r_arg1HL
-+#undef	r_arg1H
-+#undef	r_arg1L
-+
-+#undef	r_arg2HH
-+#undef	r_arg2HL
-+#undef	r_arg2H
-+#undef	r_arg2L
-+	
-+#undef	r_cnt
-+
- /**********************************
-  * This is a prologue subroutine
-  **********************************/
-@@ -899,3 +951,4 @@ __tablejump_elpm__:
- 	.endfunc
- #endif /* defined (L_tablejump_elpm) */
- 
-+#include "libgcc-fixed.S"
-diff -Naurp gcc/config/avr/t-avr gcc/config/avr/t-avr
---- gcc/config/avr/t-avr	2011-10-27 16:45:17.000000000 +0530
-+++ gcc/config/avr/t-avr	2011-10-27 16:55:55.000000000 +0530
-@@ -36,6 +36,8 @@ LIB1ASMSRC = avr/libgcc.S
- LIB1ASMFUNCS = \
- 	_mulqi3 \
- 	_mulhi3 \
-+	_mulhisi3 \
-+	_umulhisi3 \
- 	_mulsi3 \
- 	_udivmodqi4 \
- 	_divmodqi4 \
-@@ -54,6 +56,39 @@ LIB1ASMFUNCS = \
- 	_ctors \
- 	_dtors
- 
-+# Fixed point routines
-+LIB1ASMFUNCS += \
-+             _fractqqsf \
-+             _fractuqqsf \
-+             _fracthqsf \
-+             _fractuhqsf \
-+             _fracthasf \
-+             _fractuhasf \
-+             _fractsasf \
-+             _fractusasf \
-+             _fractsfqq \
-+             _fractsfuqq \
-+             _fractsfhq \
-+             _fractsfuhq \
-+             _fractsfha \
-+             _fractsfsa \
-+             _mulqq3 \
-+             _muluqq3 \
-+             _mulhq3 \
-+             _muluhq3 \
-+             _mulha3 \
-+             _muluha3 \
-+             _mulsa3 \
-+             _mulusa3 \
-+             _divqq3 \
-+             _udivuqq3 \
-+             _divhq3 \
-+             _udivuhq3 \
-+             _divha3 \
-+             _udivuha3 \
-+             _divsa3 \
-+             _udivusa3
-+
- # We do not have the DF type.
- # Most of the C functions in libgcc2 use almost all registers,
- # so use -mcall-prologues for smaller code size.
-diff -Naurp gcc/cse.c gcc/cse.c
---- gcc/cse.c	2011-10-27 16:45:17.000000000 +0530
-+++ gcc/cse.c	2011-10-27 16:55:55.000000000 +0530
-@@ -3702,9 +3702,10 @@ fold_rtx (rtx x, rtx insn)
- 			  && exact_log2 (- INTVAL (const_arg1)) >= 0)))
- 		break;
- 
--	      /* ??? Vector mode shifts by scalar
-+	      /* ??? Vector and Fixed Point shifts by scalar
- 		 shift operand are not supported yet.  */
--	      if (is_shift && VECTOR_MODE_P (mode))
-+	      if (is_shift && (VECTOR_MODE_P (mode)
-+			       || ALL_FIXED_POINT_MODE_P (mode)))
-                 break;
- 
- 	      if (is_shift
-diff -Naurp gcc/dwarf2out.c gcc/dwarf2out.c
---- gcc/dwarf2out.c	2011-10-27 16:45:17.000000000 +0530
-+++ gcc/dwarf2out.c	2011-10-27 16:55:55.000000000 +0530
-@@ -12790,6 +12790,12 @@ base_type_die (tree type)
- 
-   add_AT_unsigned (base_type_result, DW_AT_byte_size,
- 		   int_size_in_bytes (type));
-+
-+  /* version 3 dwarf specifies that for fixed-point types DW_AT_binary_scale
-+     describes the location of the decimal place */
-+  if (TREE_CODE (type) == FIXED_POINT_TYPE)
-+    add_AT_int (base_type_result, DW_AT_binary_scale, -TYPE_FBIT (type));
-+
-   add_AT_unsigned (base_type_result, DW_AT_encoding, encoding);
- 
-   return base_type_result;
-@@ -16561,7 +16567,11 @@ add_const_value_attribute (dw_die_ref di
- 
-     case HIGH:
-     case CONST_FIXED:
--      return false;
-+    {
-+        add_AT_double (die, DW_AT_const_value,
-+                          CONST_FIXED_VALUE_HIGH (rtl), CONST_FIXED_VALUE_LOW (rtl));
-+    }
-+    break;
- 
-     case MEM:
-       if (GET_CODE (XEXP (rtl, 0)) == CONST_STRING
-diff -Naurp gcc/fold-const.c gcc/fold-const.c
---- gcc/fold-const.c	2011-10-27 16:45:17.000000000 +0530
-+++ gcc/fold-const.c	2011-10-27 16:55:55.000000000 +0530
-@@ -11782,6 +11782,11 @@ fold_binary_loc (location_t loc,
-       if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) < 0)
- 	return NULL_TREE;
- 
-+      /* Since fixed point types cannot perform bitwise and, or, etc..
-+	 don't try to convert to an expression with them.  */
-+      if (TREE_CODE(type) == FIXED_POINT_TYPE)
-+	return NULL_TREE;
-+
-       /* Turn (a OP c1) OP c2 into a OP (c1+c2).  */
-       if (TREE_CODE (op0) == code && host_integerp (arg1, false)
- 	  && TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type)
-diff -Naurp gcc/varasm.c gcc/varasm.c
---- gcc/varasm.c	2011-10-27 16:45:17.000000000 +0530
-+++ gcc/varasm.c	2011-10-27 16:55:55.000000000 +0530
-@@ -2504,7 +2504,7 @@ assemble_integer (rtx x, unsigned int si
-       else
- 	mclass = MODE_INT;
- 
--      omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0);
-+      omode = mode_for_size (subsize * BITS_PER_UNIT, MODE_INT, 0);
-       imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0);
- 
-       for (i = 0; i < size; i += subsize)
diff --git a/300-gcc-xmega-support.patch b/300-gcc-xmega-support.patch
new file mode 100644
index 0000000..fadfbae
--- /dev/null
+++ b/300-gcc-xmega-support.patch
@@ -0,0 +1,171 @@
+diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
+--- gcc/config/avr/avr.c	2012-09-04 15:08:42.000000000 +0530
++++ gcc/config/avr/avr.c	2012-11-09 19:01:17.000000000 +0530
+@@ -490,6 +490,15 @@ avr_interrupt_function_p (tree func)
+   return avr_lookup_function_attribute1 (func, "interrupt");
+ }
+ 
++/* Return nonzero if FUNC is an nmi function as specified
++   by the "nmi" attribute.  */
++
++static int
++avr_nmi_function_p (tree func)
++{
++  return avr_lookup_function_attribute1 (func, "nmi");
++}
++
+ /* Return nonzero if FUNC is a signal function as specified
+    by the "signal" attribute.  */
+ 
+@@ -536,15 +545,22 @@ avr_set_current_function (tree decl)
+   cfun->machine->is_naked = avr_naked_function_p (decl);
+   cfun->machine->is_signal = avr_signal_function_p (decl);
+   cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
++  cfun->machine->is_nmi = avr_nmi_function_p (decl);
+   cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
+   cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
+ 
+-  isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
++  if (cfun->machine->is_interrupt)
++    isr = "interrupt";
++  else if (cfun->machine->is_nmi)
++    isr = "nmi";
++  else
++    isr = "signal";
+ 
+   /* Too much attributes make no sense as they request conflicting features. */
+ 
+   if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
+-      + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
++      + (cfun->machine->is_signal || cfun->machine->is_interrupt 
++          || cfun->machine->is_nmi) > 1)
+     error_at (loc, "function attributes %qs, %qs and %qs are mutually"
+                " exclusive", "OS_task", "OS_main", isr);
+ 
+@@ -555,7 +571,8 @@ avr_set_current_function (tree decl)
+     warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
+                 " no effect on %qs function", "OS_task", "OS_main", "naked");
+ 
+-  if (cfun->machine->is_interrupt || cfun->machine->is_signal)
++  if (cfun->machine->is_interrupt || cfun->machine->is_signal 
++          || cfun->machine->is_nmi)
+     {
+       tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
+       tree ret = TREE_TYPE (TREE_TYPE (decl));
+@@ -6827,6 +6844,8 @@ avr_attribute_table[] =
+     false },
+   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute,
+     false },
++  { "nmi",       0, 0, true,  false, false,  avr_handle_fndecl_attribute,
++    false },
+   { "naked",     0, 0, false, true,  true,   avr_handle_fntype_attribute,
+     false },
+   { "OS_task",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
+diff -Naurp gcc/config/avr/avr.h gcc/config/avr/avr.h
+--- gcc/config/avr/avr.h	2012-06-28 19:28:32.000000000 +0530
++++ gcc/config/avr/avr.h	2012-11-09 19:01:17.000000000 +0530
+@@ -683,6 +683,10 @@ struct GTY(()) machine_function
+   /* 'true' - if current function is a signal function 
+      as specified by the "signal" attribute.  */
+   int is_signal;
++
++  /* 'true' - if current function is an nmi 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.  */
+diff -Naurp gcc/testsuite/gcc.target/avr/misspelled-handler-warning.c gcc/testsuite/gcc.target/avr/misspelled-handler-warning.c
+--- gcc/testsuite/gcc.target/avr/misspelled-handler-warning.c	1970-01-01 05:30:00.000000000 +0530
++++ gcc/testsuite/gcc.target/avr/misspelled-handler-warning.c	2012-11-09 19:01:17.000000000 +0530
+@@ -0,0 +1,13 @@
++/* Test warning emitted for functions with nmi attribute that do
++ * not start with __vector */
++/* { dg-do compile } */
++
++
++void __attribute__((interrupt)) interrupt_fun() /* { dg-warning "'interrupt_fun' appears to be a misspelled interrupt handler" } */
++{}
++
++void __attribute__((signal)) signal_fun() /* { dg-warning "'signal_fun' appears to be a misspelled signal handler" } */
++{}
++
++void __attribute__((nmi)) nmi_fun() /* { dg-warning "'nmi_fun' appears to be a misspelled nmi handler" } */
++{}
+diff -Naurp gcc/testsuite/gcc.target/avr/xmega_const_hi_io_address.c gcc/testsuite/gcc.target/avr/xmega_const_hi_io_address.c
+--- gcc/testsuite/gcc.target/avr/xmega_const_hi_io_address.c	1970-01-01 05:30:00.000000000 +0530
++++ gcc/testsuite/gcc.target/avr/xmega_const_hi_io_address.c	2012-11-09 19:01:17.000000000 +0530
+@@ -0,0 +1,15 @@
++/* Verify that loading the contents of a constant int address in I/O range
++   uses two IN instructions with the correct SFR offset for XMEGA*/
++/* { dg-do compile } */
++/* { dg-options "-Os" } */
++/* { dg-skip-if "Only for XMEGAs" { "avr-*-*" } { "*" } { "-mmcu=atxmega128a1" } } */
++
++void func()
++{
++    volatile int val = *((int *)0x20);
++    *((int *)0x20) = 0xCAFE;
++
++}
++
++/* { dg-final { scan-assembler "\tin r\\d+,0x20\n\tin r\\d+,0x20\\+1" } } */
++/* { dg-final { scan-assembler "\tout 0x20,r\\d+\n\tout 0x20\\+1,r\\d+" } } */
+diff -Naurp gcc/testsuite/gcc.target/avr/xmega_const_qi_io_address.c gcc/testsuite/gcc.target/avr/xmega_const_qi_io_address.c
+--- gcc/testsuite/gcc.target/avr/xmega_const_qi_io_address.c	1970-01-01 05:30:00.000000000 +0530
++++ gcc/testsuite/gcc.target/avr/xmega_const_qi_io_address.c	2012-11-09 19:01:17.000000000 +0530
+@@ -0,0 +1,14 @@
++/* Verify that loading the contents of a constant address in I/O range
++   uses the IN instruction with the correct SFR offset for XMEGA*/
++/* { dg-do compile } */
++/* { dg-options "-Os" } */
++/* { dg-skip-if "Only for XMEGAs" { "avr-*-*" } { "*" } { "-mmcu=atxmega128a1" } } */
++
++void func()
++{
++    volatile char val = *((char *)0x20);
++    *((char *)0x20) = 42;
++}
++
++/* { dg-final { scan-assembler "\tin r\\d+,0x20" } } */
++/* { dg-final { scan-assembler "\tout 0x20,r\\d+" } } */
+diff -Naurp gcc/testsuite/gcc.target/avr/xmega_interrupt_no_cli.c gcc/testsuite/gcc.target/avr/xmega_interrupt_no_cli.c
+--- gcc/testsuite/gcc.target/avr/xmega_interrupt_no_cli.c	1970-01-01 05:30:00.000000000 +0530
++++ gcc/testsuite/gcc.target/avr/xmega_interrupt_no_cli.c	2012-11-09 19:01:17.000000000 +0530
+@@ -0,0 +1,14 @@
++/* Verify that XMEGA interrupts don't have a cli or sei
++   and that SPL is written before SPH*/
++/* { dg-do compile } */
++/* { dg-options "-Os" } */
++/* { dg-skip-if "Only for XMEGAs" { "avr-*-*" } { "*" } { "-mmcu=atxmega128a1" } } */
++
++void __attribute__((interrupt)) __vector_1()
++{
++    volatile int w = 19, x = 20, y = 30, z = 42;
++}
++
++/* { dg-final { scan-assembler-not "\tcli" } } */
++/* { dg-final { scan-assembler "\tout __SP_L__,r\\d+\n\tout __SP_H__,r\\d+" } } */
++
+diff -Naurp gcc/testsuite/gcc.target/avr/xmega_sfr_offsets.c gcc/testsuite/gcc.target/avr/xmega_sfr_offsets.c
+--- gcc/testsuite/gcc.target/avr/xmega_sfr_offsets.c	1970-01-01 05:30:00.000000000 +0530
++++ gcc/testsuite/gcc.target/avr/xmega_sfr_offsets.c	2012-11-09 19:01:17.000000000 +0530
+@@ -0,0 +1,18 @@
++/* Verify that SFR offsets for XMEGAs do not have the 0x20 offset 
++   and that they are saved on entry, restored on exit for an interrupt
++   function  */
++/* { dg-do compile } */
++/* { dg-options "-Os" } */
++/* { dg-skip-if "Only for XMEGAs" { "avr-*-*" } { "*" } { "-mmcu=atxmega128a1" } } */
++
++void __attribute__((interrupt)) __vector_1()
++{
++}
++
++/* { dg-final { scan-assembler "__SREG__ = 0x3f" } } */
++/* { dg-final { scan-assembler "__RAMPD__ = 0x38" } } */
++/* { dg-final { scan-assembler "\tin r0,__SREG__" } } */
++/* { dg-final { scan-assembler "\tin r0,__RAMPD__" } } */
++/* { dg-final { scan-assembler "\tpop r0\n\tout __SREG__,r0" } } */
++/* { dg-final { scan-assembler "\tpop r0\n\tout __RAMPD__,r0" } } */
++
diff --git a/301-gcc-tiny-support.patch b/301-gcc-tiny-support.patch
new file mode 100644
index 0000000..9c116a2
--- /dev/null
+++ b/301-gcc-tiny-support.patch
@@ -0,0 +1,1970 @@
+diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
+--- gcc/config/avr/avr.c	2013-01-21 18:26:07.000000000 +0530
++++ gcc/config/avr/avr.c	2013-01-21 18:40:04.000000000 +0530
+@@ -78,6 +78,17 @@
+   ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM)           \
+    / SYMBOL_FLAG_MACH_DEP)
+ 
++#define TINY_ADIW(REG1, REG2, I)                                \
++    "subi " #REG1 ",lo8(-(" #I "))" CR_TAB                        \
++    "sbci " #REG2 ",hi8(-(" #I "))"        
++
++#define TINY_SBIW(REG1, REG2, I)                                \
++    "subi " #REG1 ",lo8((" #I "))" CR_TAB                         \
++    "sbci " #REG2 ",hi8((" #I "))"        
++
++#define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO)
++#define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO)
++
+ /* Known address spaces.  The order must be the same as in the respective
+    enum from avr.h (or designated initialized must be used).  */
+ const avr_addrspace_t avr_addrspace[] =
+@@ -157,6 +168,9 @@ static bool avr_rtx_costs (rtx, int, int
+ /* Allocate registers from r25 to r8 for parameters for function calls.  */
+ #define FIRST_CUM_REG 26
+ 
++/* Last call saved register */
++#define LAST_CALLEE_SAVED_REG (AVR_TINY ? 21 : 17)
++
+ /* Implicit target register of LPM instruction (R0) */
+ extern GTY(()) rtx lpm_reg_rtx;
+ rtx lpm_reg_rtx;
+@@ -306,7 +320,7 @@ avr_option_override (void)
+   avr_addr.rampy = 0x3A + avr_current_arch->sfr_offset;
+   avr_addr.rampx = 0x39 + avr_current_arch->sfr_offset;
+   avr_addr.rampd = 0x38 + avr_current_arch->sfr_offset;
+-  avr_addr.ccp = 0x34 + avr_current_arch->sfr_offset;
++  avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_current_arch->sfr_offset;
+ 
+   /* SP: Stack Pointer (SP_H:SP_L) */
+   avr_addr.sp_l = 0x3D + avr_current_arch->sfr_offset;
+@@ -338,8 +352,8 @@ avr_init_expanders (void)
+     all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
+ 
+   lpm_reg_rtx  = all_regs_rtx[LPM_REGNO];
+-  tmp_reg_rtx  = all_regs_rtx[TMP_REGNO];
+-  zero_reg_rtx = all_regs_rtx[ZERO_REGNO];
++  tmp_reg_rtx  = all_regs_rtx[AVR_TMP_REGNO];
++  zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO];
+ 
+   lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
+ 
+@@ -351,6 +365,11 @@ avr_init_expanders (void)
+ 
+   xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
+   xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
++
++  /* TINY core does not have regs r10-r16, but avr-dimode.md expects them
++     to be present */
++  if (AVR_TINY)
++    avr_have_dimode = false; 
+ }
+ 
+ 
+@@ -792,7 +811,7 @@ sequent_regs_live (void)
+   int live_seq=0;
+   int cur_seq=0;
+ 
+-  for (reg = 0; reg < 18; ++reg)
++  for (reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
+     {
+       if (fixed_regs[reg])
+         {
+@@ -903,7 +922,7 @@ emit_push_sfr (rtx sfr, bool frame_relat
+     RTX_FRAME_RELATED_P (insn) = 1;
+   
+   /* PUSH __tmp_reg__ */
+-  emit_push_byte (TMP_REGNO, frame_related_p);
++  emit_push_byte (AVR_TMP_REGNO, frame_related_p);
+ 
+   if (clr_p)
+     {
+@@ -929,7 +948,8 @@ avr_prologue_setup_frame (HOST_WIDE_INT 
+                    && live_seq
+                    && !isr_p
+                    && !cfun->machine->is_OS_task
+-                   && !cfun->machine->is_OS_main);
++                   && !cfun->machine->is_OS_main
++                   && !AVR_TINY);
+   
+   if (minimize
+       && (frame_pointer_needed
+@@ -966,11 +986,11 @@ avr_prologue_setup_frame (HOST_WIDE_INT 
+       /* Note that live_seq always contains r28+r29, but the other
+          registers to be saved are all below 18.  */
+ 
+-      first_reg = 18 - (live_seq - 2);
++      first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
+ 
+       for (reg = 29, offset = -live_seq + 1;
+            reg >= first_reg;
+-           reg = (reg == 28 ? 17 : reg - 1), ++offset)
++           reg = (reg == 28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset)
+         {
+           rtx m, r;
+ 
+@@ -1201,10 +1221,10 @@ expand_prologue (void)
+         emit_insn (gen_enable_interrupt ());
+         
+       /* Push zero reg.  */
+-      emit_push_byte (ZERO_REGNO, true);
++      emit_push_byte (AVR_ZERO_REGNO, true);
+ 
+       /* Push tmp reg.  */
+-      emit_push_byte (TMP_REGNO, true);
++      emit_push_byte (AVR_TMP_REGNO, true);
+ 
+       /* Push SREG.  */
+       /* ??? There's no dwarf2 column reserved for SREG.  */
+@@ -1344,7 +1364,8 @@ expand_epilogue (bool sibcall_p)
+               && live_seq
+               && !isr_p
+               && !cfun->machine->is_OS_task
+-              && !cfun->machine->is_OS_main);
++              && !cfun->machine->is_OS_main
++              && !AVR_TINY);
+   
+   if (minimize
+       && (live_seq > 4
+@@ -1502,14 +1523,14 @@ expand_epilogue (bool sibcall_p)
+ 
+       /* Restore SREG using tmp_reg as scratch.  */
+       
+-      emit_pop_byte (TMP_REGNO);
++      emit_pop_byte (AVR_TMP_REGNO);
+       emit_move_insn (sreg_rtx, tmp_reg_rtx);
+ 
+       /* Restore tmp REG.  */
+-      emit_pop_byte (TMP_REGNO);
++      emit_pop_byte (AVR_TMP_REGNO);
+ 
+       /* Restore zero REG.  */
+-      emit_pop_byte (ZERO_REGNO);
++      emit_pop_byte (AVR_ZERO_REGNO);
+     }
+ 
+   if (!sibcall_p)
+@@ -2009,7 +2030,7 @@ avr_print_operand (FILE *file, rtx x, in
+             fprintf (file, "__RAMPX__");
+           else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
+             fprintf (file, "__RAMPD__");
+-          else if (AVR_XMEGA && ival == avr_addr.ccp)
++          else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp)
+             fprintf (file, "__CCP__");
+           else if (ival == avr_addr.sreg)   fprintf (file, "__SREG__");
+           else if (ival == avr_addr.sp_l)   fprintf (file, "__SP_L__");
+@@ -2052,6 +2073,13 @@ avr_print_operand (FILE *file, rtx x, in
+ 
+ 	  avr_print_operand (file, XEXP (addr, 1), 0);
+ 	}
++      else if (code == 'b')
++        {
++          if (GET_CODE (addr) != PLUS)
++	        fatal_insn ("bad address, not (reg+disp):", addr);
++
++          avr_print_operand_address (file, XEXP (addr, 0));
++        }
+       else if (code == 'p' || code == 'r')
+         {
+           if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
+@@ -2392,7 +2420,7 @@ avr_simplify_comparison_p (enum machine_
+ int
+ function_arg_regno_p(int r)
+ {
+-  return (r >= 8 && r <= 25);
++  return (AVR_TINY ? r >= 20 && r <= 25 : r >= 8 && r <= 25);
+ }
+ 
+ /* Initializing the variable cum for the state at the beginning
+@@ -2402,7 +2430,7 @@ void
+ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
+ 		      tree fndecl ATTRIBUTE_UNUSED)
+ {
+-  cum->nregs = 18;
++  cum->nregs = AVR_TINY ? 6 : 18;
+   cum->regno = FIRST_CUM_REG;
+   if (!libname && stdarg_p (fntype))
+     cum->nregs = 0;
+@@ -2900,6 +2928,25 @@ output_movhi (rtx insn, rtx xop[], int *
+   return "";
+ }
+ 
++/* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */
++static const char*
++avr_out_movqi_r_mr_reg_disp_tiny (rtx insn, rtx op[], int *plen)
++{
++  rtx dest = op[0];
++  rtx src = op[1];
++  rtx x = XEXP (src, 0);
++  op[2] = XEXP(x, 0);
++
++  avr_asm_len (TINY_ADIW (%A2, %B2, %o1) CR_TAB
++          "ld %0,%b1" , op, plen, -3);
++
++  if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
++          && !reg_unused_after (insn, XEXP (x,0)))
++      avr_asm_len (TINY_SBIW (%A2, %B2, %o1), op, plen, 2);
++
++  return "";
++}
++
+ static const char*
+ out_movqi_r_mr (rtx insn, rtx op[], int *plen)
+ {
+@@ -2913,13 +2960,18 @@ out_movqi_r_mr (rtx insn, rtx op[], int 
+         ? avr_asm_len ("in %0,%i1", op, plen, -1)
+         : avr_asm_len ("lds %0,%m1", op, plen, -2);
+     }
+-  else if (GET_CODE (x) == PLUS
++
++
++  if (GET_CODE (x) == PLUS
+            && REG_P (XEXP (x, 0))
+            && CONST_INT_P (XEXP (x, 1)))
+     {
+       /* memory access by reg+disp */
+ 
+       int disp = INTVAL (XEXP (x, 1));
++
++      if (AVR_TINY)
++        return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen);
+       
+       if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
+         {
+@@ -2941,25 +2993,105 @@ out_movqi_r_mr (rtx insn, rtx op[], int 
+         {
+           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
+              it but I have this situation with extremal optimizing options.  */
+-          
+-          avr_asm_len ("adiw r26,%o1" CR_TAB
+-                       "ld %0,X", op, plen, -2);
++
++            avr_asm_len ("adiw r26, %o1" CR_TAB
++                         "ld %0,X", op, plen, -2);
+           
+           if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
+               && !reg_unused_after (insn, XEXP (x,0)))
+             {
+-              avr_asm_len ("sbiw r26,%o1", op, plen, 1);
++              avr_asm_len ("sbiw r26, %o1", op, plen, 1);
+             }
+ 
+           return "";
+         }
+ 
+-      return avr_asm_len ("ldd %0,%1", op, plen, -1);
++        return avr_asm_len ("ldd %0,%1", op, plen, -1);
+     }
+   
+   return avr_asm_len ("ld %0,%1", op, plen, -1);
+ }
+ 
++/* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
++static const char*
++avr_out_movhi_r_mr_reg_no_disp_tiny (rtx op[], int *plen)
++{
++  rtx dest = op[0];
++  rtx src = op[1];
++  rtx base = XEXP (src, 0);
++
++  int reg_dest = true_regnum (dest);
++  int reg_base = true_regnum (base);
++
++  op[2] = base;
++
++  if (reg_dest == reg_base)         /* R = (R) */
++      return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
++              "ld %B0,%1"          CR_TAB
++              "mov %A0,__tmp_reg__", op, plen, -3);
++
++  return avr_asm_len ("ld %A0,%1"             CR_TAB                        
++          TINY_ADIW (%A2, %B2, 1) CR_TAB                       
++          "ld %B0,%1"             CR_TAB                        
++          TINY_SBIW (%A2, %B2, 1), op, plen, -6);
++
++}
++
++/* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
++static const char*
++avr_out_movhi_r_mr_reg_disp_tiny (rtx op[], int *plen)
++{
++  rtx dest = op[0];
++  rtx src = op[1];
++  rtx base = XEXP (src, 0);
++
++  int reg_dest = true_regnum (dest);
++  int reg_base = true_regnum (XEXP (base, 0));
++  op[2] = XEXP (base, 0);
++
++  if (reg_base == reg_dest)
++  {
++      return avr_asm_len (TINY_ADIW (%A2, %B2, %o1) CR_TAB
++              "ld __tmp_reg__,%b1+"    CR_TAB
++              "ld %B0,%b1"             CR_TAB 
++              "mov %A0,__tmp_reg__", op, plen, -5);
++  }
++  else
++  {
++      return avr_asm_len (TINY_ADIW (%A2, %B2, %o1) CR_TAB
++              "ld %A0,%b1+"             CR_TAB
++              "ld %B0,%b1"              CR_TAB
++              TINY_SBIW (%A2, %B2, %o1+1), op, plen, -6);
++  }
++} 
++
++/* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
++static const char*
++avr_out_movhi_r_mr_pre_dec_tiny (rtx insn, rtx op[], int *plen)
++{
++  int mem_volatile_p = 0;
++  rtx dest = op[0];
++  rtx src = op[1];
++  rtx base = XEXP (src, 0);
++  op[2] = XEXP (base, 0);
++
++  /* "volatile" forces reading low byte first, even if less efficient,
++     for correct operation with 16-bit I/O registers.  */
++  mem_volatile_p = MEM_VOLATILE_P (src);
++
++  if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
++      fatal_insn ("incorrect insn:", insn);
++
++  if (!mem_volatile_p)
++      return avr_asm_len ("ld %B0,%1" CR_TAB
++              "ld %A0,%1", op, plen, -2);
++
++  return avr_asm_len (TINY_SBIW (%A2, %B2, 2)  CR_TAB
++          "ld %A0,%p1+"   CR_TAB
++          "ld %B0,%p1"    CR_TAB
++          TINY_SBIW (%A2, %B2, 1), op, plen, -6);
++}
++
+ static const char*
+ out_movhi_r_mr (rtx insn, rtx op[], int *plen)
+ {
+@@ -2974,20 +3106,27 @@ out_movhi_r_mr (rtx insn, rtx op[], int 
+ 
+   if (reg_base > 0)
+     {
++      if (AVR_TINY)
++          return avr_out_movhi_r_mr_reg_no_disp_tiny (op, plen);
++
+       if (reg_dest == reg_base)         /* R = (R) */
+         return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
+                             "ld %B0,%1"          CR_TAB
+                             "mov %A0,__tmp_reg__", op, plen, -3);
+ 
+       if (reg_base != REG_X)
++      {
+         return avr_asm_len ("ld %A0,%1" CR_TAB
+-                            "ldd %B0,%1+1", op, plen, -2);
+-      
++                         "ldd %B0,%1+1", op, plen, -2);
++      }
++          
+       avr_asm_len ("ld %A0,X+" CR_TAB
+                    "ld %B0,X", op, plen, -2);
+           
+       if (!reg_unused_after (insn, base))
++      {
+         avr_asm_len ("sbiw r26,1", op, plen, 1);
++      }
+ 
+       return "";
+     }
+@@ -2996,6 +3135,9 @@ out_movhi_r_mr (rtx insn, rtx op[], int 
+       int disp = INTVAL (XEXP (base, 1));
+       int reg_base = true_regnum (XEXP (base, 0));
+       
++      if (AVR_TINY)
++          return avr_out_movhi_r_mr_reg_disp_tiny (op, plen);
++
+       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
+         {
+           if (REGNO (XEXP (base, 0)) != REG_Y)
+@@ -3007,7 +3149,7 @@ out_movhi_r_mr (rtx insn, rtx op[], int 
+                            "ldd %B0,Y+63"    CR_TAB
+                            "sbiw r28,%o1-62", op, plen, -4)
+ 
+-            : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
++              : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
+                            "sbci r29,hi8(-%o1)" CR_TAB
+                            "ld %A0,Y"           CR_TAB
+                            "ldd %B0,Y+1"        CR_TAB
+@@ -3041,6 +3183,9 @@ out_movhi_r_mr (rtx insn, rtx op[], int 
+     }
+   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
+     {
++      if (AVR_TINY)
++          return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen);
++
+       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
+         fatal_insn ("incorrect insn:", insn);
+ 
+@@ -3081,6 +3226,101 @@ out_movhi_r_mr (rtx insn, rtx op[], int 
+ }
+ 
+ static const char*
++avr_out_movsi_r_mr_reg_no_disp_tiny (rtx insn, rtx op[], int *l)
++{
++  rtx dest = op[0];
++  rtx src = op[1];
++  rtx base = XEXP (src, 0);
++  int reg_dest = true_regnum (dest);
++  int reg_base = true_regnum (base);
++  op[2] = base;
++
++  if (reg_dest == reg_base)
++    {
++	  /* "ld r26,-X" is undefined */
++      return *l=9, (TINY_ADIW (%A2, %B2, 3) CR_TAB
++                    "ld %D0,%1"             CR_TAB
++                    "ld %C0,-%1"            CR_TAB
++                    "ld __tmp_reg__,-%1"   CR_TAB
++                    TINY_SBIW (%A2, %B2, 1) CR_TAB
++                    "ld %A0,%1"             CR_TAB
++                    "mov %B0,__tmp_reg__");
++    }
++  else if (reg_dest == reg_base - 2)
++    {
++      return *l=5, ("ld %A0,%1+"            CR_TAB
++                    "ld %B0,%1+"            CR_TAB
++                    "ld __tmp_reg__,%1+"   CR_TAB
++                    "ld %D0,%1"            CR_TAB
++                    "mov %C0,__tmp_reg__");
++    }
++  else if (reg_unused_after (insn, base))
++    {
++      return *l=4, ("ld %A0,%1+"    CR_TAB
++                    "ld %B0,%1+"    CR_TAB 
++                    "ld %C0,%1+"    CR_TAB
++                    "ld %D0,%1");
++    }
++  else
++    {
++      return *l=6, ("ld %A0,%1+"    CR_TAB
++                    "ld %B0,%1+"    CR_TAB 
++                    "ld %C0,%1+"    CR_TAB
++                    "ld %D0,%1"     CR_TAB
++                    TINY_SBIW (%A2, %B2, 3));
++    }
++}
++
++static const char*
++avr_out_movsi_r_mr_reg_disp_tiny (rtx insn, rtx op[], int *l)
++{
++  rtx dest = op[0];
++  rtx src = op[1];
++  rtx base = XEXP (src, 0);
++  int reg_dest = true_regnum (dest);
++  int reg_base = true_regnum (XEXP (base, 0));
++  op[2] = XEXP (base, 0);
++
++  if (reg_dest == reg_base)
++    {
++	  /* "ld r26,-X" is undefined */
++      return *l=9, (TINY_ADIW (%A2, %B2, %o1+3) CR_TAB
++                    "ld %D0,%b1"                 CR_TAB
++                    "ld %C0,-%b1"                CR_TAB
++                    "ld __tmp_reg__,-%b1"        CR_TAB
++                    TINY_SBIW (%A2, %B2, 1)     CR_TAB
++                    "ld %A0,%b1"                 CR_TAB
++                    "mov %B0,__tmp_reg__");
++    }
++  else if (reg_dest == reg_base - 2)
++    {
++      return *l=7, (TINY_ADIW (%A2, %B2, %o1) CR_TAB
++                    "ld %A0,%b1+"              CR_TAB
++                    "ld %B0,%b1+"              CR_TAB
++                    "ld __tmp_reg__,%b1+"      CR_TAB
++                    "ld %D0,%b1"               CR_TAB
++                    "mov %C0,__tmp_reg__");
++    }
++  else if (reg_unused_after (insn, XEXP (base, 0)))
++    {
++      return *l=6, (TINY_ADIW (%A2, %B2, %o1) CR_TAB
++                    "ld %A0,%b1+"              CR_TAB
++                    "ld %B0,%b1+"              CR_TAB 
++                    "ld %C0,%b1+"              CR_TAB
++                    "ld %D0,%b1");
++    }
++  else
++    {
++      return *l=8, (TINY_ADIW (%A2, %B2, %o1) CR_TAB
++                    "ld %A0,%b1+"              CR_TAB
++                    "ld %B0,%b1+"              CR_TAB 
++                    "ld %C0,%b1+"              CR_TAB
++                    "ld %D0,%b1"               CR_TAB
++                    TINY_SBIW (%A2, %B2, %o1+3));
++    }
++}
++
++static const char*
+ out_movsi_r_mr (rtx insn, rtx op[], int *l)
+ {
+   rtx dest = op[0];
+@@ -3095,6 +3335,9 @@ out_movsi_r_mr (rtx insn, rtx op[], int 
+   
+   if (reg_base > 0)
+     {
++      if (AVR_TINY)
++        return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l);
++
+       if (reg_base == REG_X)        /* (R26) */
+         {
+           if (reg_dest == REG_X)
+@@ -3149,6 +3392,9 @@ out_movsi_r_mr (rtx insn, rtx op[], int 
+     {
+       int disp = INTVAL (XEXP (base, 1));
+       
++      if (AVR_TINY)
++        return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l);
++
+       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
+ 	{
+ 	  if (REGNO (XEXP (base, 0)) != REG_Y)
+@@ -3242,6 +3488,113 @@ out_movsi_r_mr (rtx insn, rtx op[], int 
+ }
+ 
+ static const char*
++avr_out_movsi_mr_r_reg_no_disp_tiny (rtx insn, rtx op[], int *l)
++{
++  rtx dest = op[0];
++  rtx src = op[1];
++  rtx base = XEXP (dest, 0);
++  int reg_base = true_regnum (base);
++  int reg_src = true_regnum (src);
++  op[2] = base;
++  
++  if (reg_base == reg_src)
++    {
++	  /* "ld r26,-X" is undefined */
++      if (reg_unused_after (insn, base))
++        { 
++          return *l=7, ("mov __tmp_reg__, %B1"  CR_TAB
++                        "st %0,%A1"             CR_TAB
++                        TINY_ADIW (%A2, %B2, 1) CR_TAB
++                        "st %0+,__tmp_reg__"    CR_TAB
++                        "st %0+,%C1"            CR_TAB
++                        "st %0+,%D1");
++        }
++      else
++        {
++          return *l=9, ("mov __tmp_reg__, %B1"  CR_TAB
++                        "st %0,%A1"             CR_TAB
++                        TINY_ADIW (%A2, %B2, 1) CR_TAB
++                        "st %0+,__tmp_reg__"    CR_TAB
++                        "st %0+,%C1"            CR_TAB
++                        "st %0+,%D1"            CR_TAB
++                        TINY_SBIW (%A2, %B2, 3));
++        }
++    }
++    else if (reg_base == reg_src + 2)
++      {
++        if (reg_unused_after (insn, base))
++          return *l=7, ("mov __zero_reg__,%C1" CR_TAB
++                        "mov __tmp_reg__,%D1"  CR_TAB
++                        "st %0+,%A1"           CR_TAB
++                        "st %0+,%B1"           CR_TAB
++                        "st %0+,__zero_reg__"  CR_TAB
++                        "st %0,__tmp_reg__"    CR_TAB
++                        "clr __zero_reg__");
++        else
++          return *l=9, ("mov __zero_reg__,%C1" CR_TAB
++                        "mov __tmp_reg__,%D1"  CR_TAB
++                        "st %0+,%A1"           CR_TAB
++                        "st %0+,%B1"           CR_TAB
++                        "st %0+,__zero_reg__"  CR_TAB
++                        "st %0,__tmp_reg__"    CR_TAB
++                        "clr __zero_reg__"     CR_TAB
++                        TINY_SBIW (%A2, %B2, 3));
++      }
++
++    return *l=6, ("st %0+,%A1" CR_TAB
++                  "st %0+,%B1" CR_TAB
++                  "st %0+,%C1" CR_TAB
++                  "st %0,%D1"  CR_TAB
++                  TINY_SBIW (%A2, %B2, 3));
++}
++
++static const char*
++avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l)
++{
++  rtx dest = op[0];
++  rtx src = op[1];
++  rtx base = XEXP (dest, 0);
++  int reg_base = REGNO (XEXP (base, 0));
++  int reg_src =true_regnum (src);
++
++  op[2] = XEXP (base, 0);
++
++  if (reg_base == reg_src)
++    {
++	  *l = 11;
++	  return ("mov __tmp_reg__,%A2"        CR_TAB
++		      "mov __zero_reg__,%B2"       CR_TAB
++              TINY_ADIW (%A2, %B2, %o0)    CR_TAB
++		      "st %b0+,__tmp_reg__"        CR_TAB
++		      "st %b0+,__zero_reg__"       CR_TAB
++		      "st %b0+,%C2"                CR_TAB
++		      "st %b0,%D2"                 CR_TAB
++		      "clr __zero_reg__"           CR_TAB
++		      TINY_SBIW (%A2, %B2, %o0+3));
++	 }
++  else if (reg_src == reg_base - 2)
++    {
++	  *l = 11;
++	  return ("mov __tmp_reg__,%C2"         CR_TAB
++		      "mov __zero_reg__,%D2"        CR_TAB
++		      TINY_ADIW (%A2, %B2, %o0)     CR_TAB
++		      "st %b0+,%A0"                 CR_TAB
++		      "st %b0+,%B0"                 CR_TAB
++		      "st %b0+,__tmp_reg__"         CR_TAB
++		      "st %b0,__zero_reg__"         CR_TAB
++		      "clr __zero_reg__"            CR_TAB
++		      TINY_SBIW (%A2, %B2, %o0+3));
++	    }
++  *l = 8;
++  return (TINY_ADIW (%A2, %B2, %o0)     CR_TAB
++		  "st %b0+,%A1"                 CR_TAB
++		  "st %b0+,%B1"                 CR_TAB
++		  "st %b0+,%C1"                 CR_TAB
++		  "st %b0,%D1"                  CR_TAB
++		  TINY_SBIW (%A2, %B2, %o0+3));
++}
++
++static const char*
+ out_movsi_mr_r (rtx insn, rtx op[], int *l)
+ {
+   rtx dest = op[0];
+@@ -3261,6 +3614,9 @@ out_movsi_mr_r (rtx insn, rtx op[], int 
+                  "sts %m0+3,%D1");
+   if (reg_base > 0)                 /* (r) */
<Skipped 11291 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/crossavr-gcc.git/commitdiff/64c2fd3a8074811ce245fd562fc09a19fb7baf51




More information about the pld-cvs-commit mailing list