diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 981d4895cd545a8dd2bedcf20473581c2043187e..1810dbeccb8a04dc48be1713ee0816089aa75fba 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2013-07-19  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/57516
+	* config/avr/avr-fixed.md (round<mode>3_const): Turn expander to insn.
+	* config/avr/avr.md (adjust_len): Add `round'.
+	* config/avr/avr-protos.h (avr_out_round): New prototype.
+	(avr_out_plus): Add `out_label' argument.
+	* config/avr/avr.c (avr_out_plus_1): Add `out_label' argument.
+	(avr_out_plus): Pass down `out_label' to avr_out_plus_1.
+	Handle the case where `insn' is just a pattern.
+	(avr_out_bitop): Handle the case where `insn' is just a pattern.
+	(avr_out_round): New function.
+	(avr_adjust_insn_length): Handle ADJUST_LEN_ROUND.
+
 2013-07-18  David Holsgrove <david.holsgrove@xilinx.com>
 
 	* config/microblaze/microblaze.c (microblaze_expand_prologue):
diff --git a/gcc/config/avr/avr-fixed.md b/gcc/config/avr/avr-fixed.md
index 7d9b525ef6cfc06edec53b63990a1b7ba3714321..b2f0b9aa144ec383175f231ae549b5ee24da5de8 100644
--- a/gcc/config/avr/avr-fixed.md
+++ b/gcc/config/avr/avr-fixed.md
@@ -447,49 +447,18 @@
 ;; "roundqq3_const"  "rounduqq3_const"
 ;; "roundhq3_const"  "rounduhq3_const"  "roundha3_const"  "rounduha3_const"
 ;; "roundsq3_const"  "roundusq3_const"  "roundsa3_const"  "roundusa3_const"
-(define_expand "round<mode>3_const"
-  [(parallel [(match_operand:ALL124QA 0 "register_operand" "")
-              (match_operand:ALL124QA 1 "register_operand" "")
-              (match_operand:HI 2 "const_int_operand" "")])]
+(define_insn "round<mode>3_const"
+  [(set (match_operand:ALL124QA 0 "register_operand"                  "=d")
+        (unspec:ALL124QA [(match_operand:ALL124QA 1 "register_operand" "0")
+                          (match_operand:HI 2 "const_int_operand"      "n")
+                          (const_int 0)]
+                         UNSPEC_ROUND))]
   ""
   {
-    // The rounding point RP is $2.  The smallest fractional
-    // bit that is not cleared by the rounding is 2^(-RP).
-
-    enum machine_mode imode = int_mode_for_mode (<MODE>mode);
-    int fbit = (int) GET_MODE_FBIT (<MODE>mode);
-
-    // Add-Saturate  1/2 * 2^(-RP)
-
-    double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (operands[2]));
-    rtx x_add = const_fixed_from_double_int (i_add, <MODE>mode);
-
-    if (SIGNED_FIXED_POINT_MODE_P (<MODE>mode))
-      emit_move_insn (operands[0],
-                      gen_rtx_SS_PLUS (<MODE>mode, operands[1], x_add));
-    else
-      emit_move_insn (operands[0],
-                      gen_rtx_US_PLUS (<MODE>mode, operands[1], x_add));
-
-    // Keep  all bits from RP and higher:   ... 2^(-RP)
-    // Clear all bits from RP+1 and lower:              2^(-RP-1) ...
-    // Rounding point                           ^^^^^^^
-    // Added above                                      ^^^^^^^^^
-
-    rtx xreg = simplify_gen_subreg (imode, operands[0], <MODE>mode, 0);
-    rtx xmask = immed_double_int_const (-i_add - i_add, imode);
-
-    if (SImode == imode)
-      emit_insn (gen_andsi3 (xreg, xreg, xmask));
-    else if (HImode == imode)
-      emit_insn (gen_andhi3 (xreg, xreg, xmask));
-    else if (QImode == imode)
-      emit_insn (gen_andqi3 (xreg, xreg, xmask));
-    else
-      gcc_unreachable();
-
-    DONE;
-  })
+    return avr_out_round (insn, operands);
+  }
+  [(set_attr "cc" "clobber")
+   (set_attr "adjust_len" "round")])
 
 
 ;; "*roundqq3.libgcc"  "*rounduqq3.libgcc"
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index 5246d063799f7b3b69af04f7a9f66a89d65aa006..21ad26a6f3420ec2e351194615f59f4936560f6e 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -86,7 +86,8 @@ extern int avr_starting_frame_offset (void);
 extern void avr_output_addr_vec_elt (FILE *stream, int value);
 extern const char *avr_out_sbxx_branch (rtx insn, rtx operands[]);
 extern const char* avr_out_bitop (rtx, rtx*, int*);
-extern const char* avr_out_plus (rtx, rtx*, int* =NULL, int* =NULL);
+extern const char* avr_out_plus (rtx, rtx*, int* =NULL, int* =NULL, bool =true);
+extern const char* avr_out_round (rtx, rtx*, int* =NULL);
 extern const char* avr_out_addto_sp (rtx*, int*);
 extern const char* avr_out_xload (rtx, rtx*, int*);
 extern const char* avr_out_movmem (rtx, rtx*, int*);
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index f8a43e5715e04c9d9321c53098b48ea4806719a5..50100bf55134d0882dbb762ce2a94282c2ad5662 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -6232,11 +6232,14 @@ lshrsi3_out (rtx insn, rtx operands[], int *len)
    the subtrahend in the original insn, provided it is a compile time constant.
    In all other cases, SIGN is 0.
 
-   Return "".  */
+   If OUT_LABEL is true, print the final 0: label which is needed for
+   saturated addition / subtraction.  The only case where OUT_LABEL = false
+   is useful is for saturated addition / subtraction performed during
+   fixed-point rounding, cf. `avr_out_round'.  */
 
 static void
 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
-                enum rtx_code code_sat = UNKNOWN, int sign = 0)
+                enum rtx_code code_sat, int sign, bool out_label)
 {
   /* MODE of the operation.  */
   enum machine_mode mode = GET_MODE (xop[0]);
@@ -6675,7 +6678,8 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
                      "mov %r0+5,%0", xop, plen, 4);
     }
 
-  avr_asm_len ("0:", op, plen, 0);
+  if (out_label)
+    avr_asm_len ("0:", op, plen, 0);
 }
 
 
@@ -6713,8 +6717,8 @@ avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen, int *pcc)
 
 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
 
-   INSN is a single_set insn with a binary operation as SET_SRC that is
-   one of:  PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
+   INSN is a single_set insn or an insn pattern with a binary operation as
+   SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
 
    XOP are the operands of INSN.  In the case of 64-bit operations with
    constant XOP[] has just one element:  The summand/subtrahend in XOP[0].
@@ -6729,19 +6733,22 @@ avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen, int *pcc)
 
    PLEN and PCC default to NULL.
 
+   OUT_LABEL defaults to TRUE.  For a description, see AVR_OUT_PLUS_1.
+
    Return ""  */
 
 const char*
-avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc)
+avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc, bool out_label)
 {
   int cc_plus, cc_minus, cc_dummy;
   int len_plus, len_minus;
   rtx op[4];
-  rtx xdest = SET_DEST (single_set (insn));
+  rtx xpattern = INSN_P (insn) ? single_set (insn) : insn;
+  rtx xdest = SET_DEST (xpattern);
   enum machine_mode mode = GET_MODE (xdest);
   enum machine_mode imode = int_mode_for_mode (mode);
   int n_bytes = GET_MODE_SIZE (mode);
-  enum rtx_code code_sat = GET_CODE (SET_SRC (single_set (insn)));
+  enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
   enum rtx_code code
     = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
        ? PLUS : MINUS);
@@ -6756,7 +6763,7 @@ avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc)
 
   if (n_bytes <= 4 && REG_P (xop[2]))
     {
-      avr_out_plus_1 (xop, plen, code, pcc, code_sat);
+      avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label);
       return "";
     }
 
@@ -6783,7 +6790,8 @@ avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc)
   /* Saturations and 64-bit operations don't have a clobber operand.
      For the other cases, the caller will provide a proper XOP[3].  */
 
-  op[3] = PARALLEL == GET_CODE (PATTERN (insn)) ? xop[3] : NULL_RTX;
+  xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
+  op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
 
   /* Saturation will need the sign of the original operand.  */
 
@@ -6798,8 +6806,8 @@ avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc)
 
   /* Work out the shortest sequence.  */
 
-  avr_out_plus_1 (op, &len_minus, MINUS, &cc_plus, code_sat, sign);
-  avr_out_plus_1 (op, &len_plus, PLUS, &cc_minus, code_sat, sign);
+  avr_out_plus_1 (op, &len_minus, MINUS, &cc_plus, code_sat, sign, out_label);
+  avr_out_plus_1 (op, &len_plus, PLUS, &cc_minus, code_sat, sign, out_label);
 
   if (plen)
     {
@@ -6807,9 +6815,9 @@ avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc)
       *pcc  = (len_minus <= len_plus) ? cc_minus : cc_plus;
     }
   else if (len_minus <= len_plus)
-    avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign);
+    avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign, out_label);
   else
-    avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign);
+    avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign, out_label);
 
   return "";
 }
@@ -6823,13 +6831,15 @@ avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc)
    and return "".  If PLEN == NULL, print assembler instructions to perform the
    operation; otherwise, set *PLEN to the length of the instruction sequence
    (in words) printed with PLEN == NULL.  XOP[3] is either an 8-bit clobber
-   register or SCRATCH if no clobber register is needed for the operation.  */
+   register or SCRATCH if no clobber register is needed for the operation.
+   INSN is an INSN_P or a pattern of an insn.  */
 
 const char*
 avr_out_bitop (rtx insn, rtx *xop, int *plen)
 {
   /* CODE and MODE of the operation.  */
-  enum rtx_code code = GET_CODE (SET_SRC (single_set (insn)));
+  rtx xpattern = INSN_P (insn) ? single_set (insn) : insn;
+  enum rtx_code code = GET_CODE (SET_SRC (xpattern));
   enum machine_mode mode = GET_MODE (xop[0]);
 
   /* Number of bytes to operate on.  */
@@ -7332,6 +7342,67 @@ avr_out_fract (rtx insn, rtx operands[], bool intsigned, int *plen)
 }
 
 
+/* Output fixed-point rounding.  XOP[0] = XOP[1] is the operand to round.
+   XOP[2] is the rounding point, a CONST_INT.  The function prints the
+   instruction sequence if PLEN = NULL and computes the length in words
+   of the sequence if PLEN != NULL.  Most of this function deals with
+   preparing operands for calls to `avr_out_plus' and `avr_out_bitop'.  */
+
+const char*
+avr_out_round (rtx insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
+{
+  enum machine_mode mode = GET_MODE (xop[0]);
+  enum machine_mode imode = int_mode_for_mode (mode);
+  // The smallest fractional bit not cleared by the rounding is 2^(-RP).
+  int fbit = (int) GET_MODE_FBIT (mode);
+  double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
+  // Lengths of PLUS and AND parts.
+  int len_add = 0, *plen_add = plen ? &len_add : NULL;
+  int len_and = 0, *plen_and = plen ? &len_and : NULL;
+
+  // Add-Saturate  1/2 * 2^(-RP).  Don't print the label "0:" when printing
+  // the saturated addition so that we can emit the "rjmp 1f" before the
+  // "0:" below.
+
+  rtx xadd = const_fixed_from_double_int (i_add, mode);
+  rtx xpattern, xsrc, op[4];
+
+  xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
+    ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
+    : gen_rtx_US_PLUS (mode, xop[1], xadd);
+  xpattern = gen_rtx_SET (VOIDmode, xop[0], xsrc);
+
+  op[0] = xop[0];
+  op[1] = xop[1];
+  op[2] = xadd;
+  avr_out_plus (xpattern, op, plen_add, NULL, false /* Don't print "0:" */);
+
+  avr_asm_len ("rjmp 1f" CR_TAB
+               "0:", NULL, plen_add, 1);
+
+  // Keep  all bits from RP and higher:   ... 2^(-RP)
+  // Clear all bits from RP+1 and lower:              2^(-RP-1) ...
+  // Rounding point                           ^^^^^^^
+  // Added above                                      ^^^^^^^^^
+  rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
+  rtx xmask = immed_double_int_const (-i_add - i_add, imode);
+
+  xpattern = gen_rtx_SET (VOIDmode, xreg, gen_rtx_AND (imode, xreg, xmask));
+
+  op[0] = xreg;
+  op[1] = xreg;
+  op[2] = xmask;
+  op[3] = gen_rtx_SCRATCH (QImode);
+  avr_out_bitop (xpattern, op, plen_and);
+  avr_asm_len ("1:", NULL, plen, 0);
+
+  if (plen)
+    *plen = len_add + len_and;
+
+  return "";
+}
+
+
 /* Create RTL split patterns for byte sized rotate expressions.  This
   produces a series of move instructions and considers overlap situations.
   Overlapping non-HImode operands need a scratch register.  */
@@ -7540,6 +7611,7 @@ avr_adjust_insn_length (rtx insn, int len)
 
     case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
     case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
+    case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
 
     case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
     case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index e9f5d038f1f4bcd73b03ef25044501329cf35ca1..f2681233acee549114e42dc678777e244e268157 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -140,7 +140,7 @@
   "out_bitop, plus, addto_sp,
    tsthi, tstpsi, tstsi, compare, compare64, call,
    mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
-   ufract, sfract,
+   ufract, sfract, round,
    xload, lpm, movmem,
    ashlqi, ashrqi, lshrqi,
    ashlhi, ashrhi, lshrhi,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d5f4c32de0272484ff3cde53c83f8b1361067f91..9c8bfe331029ada652a122dfc91b5f1d1bdab43e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2013-07-19  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/57516
+	* gcc.target/avr/torture/builtins-4-roundfx.c (test2hr, test2k):
+	Adjust to corrected rounding.
+
 2013-07-19  Georg-Johann Lay  <avr@gjlay.de>
 
 	* lib/target-supports.exp (check_effective_target_cilkplus): New proc.
diff --git a/gcc/testsuite/gcc.target/avr/torture/builtins-4-roundfx.c b/gcc/testsuite/gcc.target/avr/torture/builtins-4-roundfx.c
index 6ad0775553a09a31c9b5bb94a4d6cf10d147af46..46e915a6c8755f14a68dbe172dba0660a333a358 100644
--- a/gcc/testsuite/gcc.target/avr/torture/builtins-4-roundfx.c
+++ b/gcc/testsuite/gcc.target/avr/torture/builtins-4-roundfx.c
@@ -72,11 +72,11 @@ DEFTEST1 (long long accum, llk)
 
 static void test2hr (void)
 {
-  TEST2 (hr, 1, 0x7f, 0x40);
-  TEST2 (hr, 2, 0x7f, 0b1100000);
-  TEST2 (hr, 3, 0x7f, 0b1110000);
-  TEST2 (hr, 4, 0x7f, 0b1111000);
-
+  TEST2 (hr, 1, 0x7f, 0x7f);
+  TEST2 (hr, 2, 0x70, 0x7f);
+  TEST2 (hr, 3, 0x78, 0x7f);
+  TEST2 (hr, 4, 0x7f, 0x7f);
+ 
   TEST2 (uhr, 1, 0x7f, 0x80);
   TEST2 (uhr, 2, 0x7f, 0x80);
   TEST2 (uhr, 3, 0x7f, 0x80);
@@ -85,10 +85,13 @@ static void test2hr (void)
 
 void test2k (void)
 {
-  TEST2 (k, 1, 0x7fffffff, 0x7fff8000 | 0b100000000000000);
-  TEST2 (k, 2, 0x7fffffff, 0x7fff8000 | 0b110000000000000);
-  TEST2 (k, 3, 0x7fffffff, 0x7fff8000 | 0b111000000000000);
-  TEST2 (k, 4, 0x7fffffff, 0x7fff8000 | 0b111100000000000);
+  TEST2 (k, 1, 0x7fffff00, 0x7fffffff);
+  TEST2 (k, 2, 0x7ffffff0, 0x7fffffff);
+  TEST2 (k, 2, 0x7ffff000, 0x7fffffff);
+  TEST2 (k, 3, 0x7ffff000, 0x7ffff000);
+  TEST2 (k, 3, 0x7ffff800, 0x7fffffff);
+  TEST2 (k, 3, 0x7ffff7ff, 0x7ffff000);
+  TEST2 (k, 4, 0x7ffff7ff, 0x7ffff800);
 
   TEST2 (uk, 1, 0x7fffffff, 1ul << 31);
   TEST2 (uk, 2, 0x7fffffff, 1ul << 31);
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 506fa43bdc02146798657aac308e6c18b650a43f..9020a64394637858d48c39bbd45321d4ad575b61 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,11 @@
+2013-07-19  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/57516
+	* config/avr/lib1funcs-fixed.S (__roundqq3, __rounduqq3)
+	(__round_s2_const, __round_u2_const)
+	(__round_s4_const, __round_u4_const, __round_x8):
+	Saturate result if addition result cannot be represented.
+
 2013-07-15  Matthias Klose  <doko@ubuntu.com>
 
 	* libgcc2.c: Don't include <limits.h>.
diff --git a/libgcc/config/avr/lib1funcs-fixed.S b/libgcc/config/avr/lib1funcs-fixed.S
index d80389ce2ee70a72054c68a17882c7d328057f67..f920891e19e8c4656d3811ed6fd331c931ff48df 100644
--- a/libgcc/config/avr/lib1funcs-fixed.S
+++ b/libgcc/config/avr/lib1funcs-fixed.S
@@ -1464,12 +1464,13 @@ DEFUN  __roundqq3
     ;; Add-Saturate 2^{-RP-1}
     add     A0, C0
     brvc 0f
-    ldi     A0, 0x7f
+    ldi     C0, 0x7f
+    rjmp 9f
 0:  ;; Mask out bits beyond RP
     lsl     C0
     neg     C0
     and     C0, A0
-    mov     C1, __tmp_reg__
+9:  mov     C1, __tmp_reg__
     ret
 ENDF  __roundqq3
 #endif /* L_roundqq3 */
@@ -1488,12 +1489,13 @@ DEFUN  __rounduqq3
     ;; Add-Saturate 2^{-RP-1}
     add     A0, C0
     brcc 0f
-    ldi     A0, 0xff
+    ldi     C0, 0xff
+    rjmp 9f
 0:  ;; Mask out bits beyond RP
     lsl     C0
     neg     C0
     and     C0, A0
-    mov     C1, __tmp_reg__
+9:  mov     C1, __tmp_reg__
     ret
 ENDF  __rounduqq3
 #endif /* L_rounduqq3 */
@@ -1565,16 +1567,17 @@ ENDF  __rounduha3
 
 DEFUN  __round_s2_const
     brvc 2f
-    ldi     A1, 0x7f
+    ldi     C1, 0x7f
     rjmp 1f
     ;; FALLTHRU (Barrier)
 ENDF  __round_s2_const
 
 DEFUN __round_u2_const
     brcc 2f
-    ldi     A1, 0xff
+    ldi     C1, 0xff
 1:
-    ldi     A0, 0xff
+    ldi     C0, 0xff
+    rjmp 9f
 2:
     ;; Saturation is performed now.
     ;; Currently, we have C[] = 2^{-RP-1}
@@ -1586,7 +1589,7 @@ DEFUN __round_u2_const
     ;; Clear the bits beyond the rounding point.
     and     C0, A0
     and     C1, A1
-    ret
+9:  ret
 ENDF  __round_u2_const
 
 #endif /* L_round_2_const */
@@ -1681,18 +1684,19 @@ ENDF  __roundusa3
 
 DEFUN  __round_s4_const
     brvc 2f
-    ldi     A3, 0x7f
+    ldi     C3, 0x7f
     rjmp 1f
     ;; FALLTHRU (Barrier)
 ENDF  __round_s4_const
 
 DEFUN __round_u4_const
     brcc 2f
-    ldi     A3, 0xff
+    ldi     C3, 0xff
 1:
-    ldi     A2, 0xff
-    ldi     A1, 0xff
-    ldi     A0, 0xff
+    ldi     C2, 0xff
+    ldi     C1, 0xff
+    ldi     C0, 0xff
+    rjmp 9f
 2:
     ;; Saturation is performed now.
     ;; Currently, we have C[] = 2^{-RP-1}
@@ -1707,7 +1711,7 @@ DEFUN __round_u4_const
     and     C1, A1
     and     C2, A2
     and     C3, A3
-    ret
+9:  ret
 ENDF  __round_u4_const
 
 #endif /* L_round_4_const */
@@ -1847,12 +1851,13 @@ DEFUN __round_x8
 1:  ;; Unsigned
     brcc    3f
     ;; Unsigned overflow: A[] = 0xff...
-2:  ldi     A7, 0xff
-    ldi     A6, 0xff
-    wmov    A0, A6
-    wmov    A2, A6
-    wmov    A4, A6
-    bld     A7, 7
+2:  ldi     C7, 0xff
+    ldi     C6, 0xff
+    wmov    C0, C6
+    wmov    C2, C6
+    wmov    C4, C6
+    bld     C7, 7
+    rjmp 9f
 3:
     ;;  C[] = -C[] - C[]
     push    A0
@@ -1869,7 +1874,7 @@ DEFUN __round_x8
     and     C5, A5
     and     C6, A6
     and     C7, A7
-    ;; Epilogue
+9:  ;; Epilogue
     pop r29
     pop r28
     pop r17