diff mbox

[AVR] Housekeeping insn attributes & remove assembler dialect

Message ID 4E9C3C39.7050705@gjlay.de
State New
Headers show

Commit Message

Georg-Johann Lay Oct. 17, 2011, 2:31 p.m. UTC
This is more code clean-up for insn attributes.

It removes "mcu_have_movw", "mcu_mega" and defines "enabled" and "isa"
attributes instead.

The "isa" attribute which triggers "enabled" is a replacement for AVR_HAVE_MOVW
assembler dialect.  We don't actually support assembler dialects but different
ISAs so that an attribute that reflects ISA capabilities seems more appropriate
and straight forward here. Moreover, it's easier to write down different
instruction lengths (which wouldn't occur if it was just an assembler dialect).

The only notable change is to epilogue_restores:

    (set (reg:HI REG_Y)
         (plus:HI (reg:HI REG_Y)
                  (match_operand:HI 0 "immediate_operand" "i,i")))
-   (set (reg:HI REG_SP)
-        (reg:HI REG_Y))
+   (set (reg:HI REG_SP)
+        (plus:HI (reg:HI REG_Y)
+                 (match_dup 0)))

The original code does not quite represent what the insn does:

A PARALLEL's actions all happen simultaneously, not in sequence.
Thus, an instruction sequence like
    Y  = Y + const
    SP = Y
has wo be written in RTL as
    Y  = Y + const
    SP = Y + const
and *not* as
    Y  = Y + const
    SP = Y

The patch passes without regressions.

The patch passes with 2 more regressions if the test suite is run with
-mcall-prologues, but the two additional run-fails
	./gcc.dg/sibcall-3.c
	./gcc.dg/sibcall-4.c
are because tail call optimization is turned off at -mcall-prologues,
see avr.c:avr_function_ok_for_sibcall().

Ok for trunk?

Johann

	* config/avr/avr.h (ASSEMBLER_DIALECT): Remove.
	* config/avr/avr.md (mcu_have_movw, mcu_mega): Remove attributes.
	(adjust_len): Add alternative "call".
	(isa, enabled): New insn attributes.
	(length): Use match_test with AVR_HAVE_JMP_CALL instead of
	mcu_mega attribute.
	(*sbrx_branch<mode>): Ditto.
	(*sbrx_and_branch<mode>): Ditto.
	(*sbix_branch): Ditto.
	(*sbix_branch_bit7): Ditto.
	(*sbix_branch_tmp): Ditto.
	(*sbix_branch_tmp_bit7): Ditto.
	(jump): Ditto.
	(negsi2): Use attribute "isa" instead of assembler dialect.
	(extendhisi2): Ditto.
	(call_insn, call_value_insn): Set adjust_len attribute.
	(indirect_jump): Indent to coding rules.
	(call_prologue_saves): Use isa attribute instead of mcu_mega.
	(epilogue_restores): Ditto.  Fix setting of SP as described in the
	RTX pattern.
	(*indirect_jump): Fusion of *jcindirect_jump, *njcindirect_jump
	and *indirect_jump_avr6.
	(*tablejump): Fusion of *tablejump_rjmp and *tablejump_lib.
	(*jcindirect_jump, *njcindirect_jump, *indirect_jump_avr6): Remove.
	(*tablejump_rjmp, *tablejump_lib): Remove.
	* config/avr/avr.c (adjust_insn_length): Handle ADJUST_LEN_CALL.

Comments

Denis Chertykov Oct. 17, 2011, 4:45 p.m. UTC | #1
2011/10/17 Georg-Johann Lay <avr@gjlay.de>:
> This is more code clean-up for insn attributes.
>
> It removes "mcu_have_movw", "mcu_mega" and defines "enabled" and "isa"
> attributes instead.
>
> The "isa" attribute which triggers "enabled" is a replacement for AVR_HAVE_MOVW
> assembler dialect.  We don't actually support assembler dialects but different
> ISAs so that an attribute that reflects ISA capabilities seems more appropriate
> and straight forward here. Moreover, it's easier to write down different
> instruction lengths (which wouldn't occur if it was just an assembler dialect).
>
> The only notable change is to epilogue_restores:
>
>    (set (reg:HI REG_Y)
>         (plus:HI (reg:HI REG_Y)
>                  (match_operand:HI 0 "immediate_operand" "i,i")))
> -   (set (reg:HI REG_SP)
> -        (reg:HI REG_Y))
> +   (set (reg:HI REG_SP)
> +        (plus:HI (reg:HI REG_Y)
> +                 (match_dup 0)))
>
> The original code does not quite represent what the insn does:
>
> A PARALLEL's actions all happen simultaneously, not in sequence.
> Thus, an instruction sequence like
>    Y  = Y + const
>    SP = Y
> has wo be written in RTL as
>    Y  = Y + const
>    SP = Y + const
> and *not* as
>    Y  = Y + const
>    SP = Y
>
> The patch passes without regressions.
>
> The patch passes with 2 more regressions if the test suite is run with
> -mcall-prologues, but the two additional run-fails
>        ./gcc.dg/sibcall-3.c
>        ./gcc.dg/sibcall-4.c
> are because tail call optimization is turned off at -mcall-prologues,
> see avr.c:avr_function_ok_for_sibcall().
>
> Ok for trunk?
>

Approved.

Denis.
diff mbox

Patch

Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md	(revision 180076)
+++ config/avr/avr.md	(working copy)
@@ -84,17 +84,6 @@  (define_attr "cc" "none,set_czn,set_zn,s
 (define_attr "type" "branch,branch1,arith,xcall"
   (const_string "arith"))
 
-(define_attr "mcu_have_movw" "yes,no"
-  (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
-		       (const_string "yes")
-		       (const_string "no"))))
-
-(define_attr "mcu_mega" "yes,no"
-  (const (if_then_else (symbol_ref "AVR_HAVE_JMP_CALL")
-		       (const_string "yes")
-		       (const_string "no"))))
-  
-
 ;; The size of instructions in bytes.
 ;; XXX may depend from "cc"
 
@@ -124,7 +113,7 @@  (define_attr "length" ""
                                      (const_int 3)
                                      (const_int 4)))
 	 (eq_attr "type" "xcall")
-	 (if_then_else (eq_attr "mcu_mega" "no")
+	 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
 		       (const_int 1)
 		       (const_int 2))]
         (const_int 2)))
@@ -133,11 +122,10 @@  (define_attr "length" ""
 ;; Following insn attribute tells if and how the adjustment has to be
 ;; done:
 ;;     no     No adjustment needed; attribute "length" is fine.
-;;     yes    Analyse pattern in adjust_insn_length by hand.
 ;; Otherwise do special processing depending on the attribute.
 
 (define_attr "adjust_len"
-  "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare,
+  "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare, call,
    mov8, mov16, mov32, reload_in16, reload_in32,
    ashlqi, ashrqi, lshrqi,
    ashlhi, ashrhi, lshrhi,
@@ -145,6 +133,50 @@  (define_attr "adjust_len"
    no"
   (const_string "no"))
 
+;; Flavours of instruction set architecture (ISA), used in enabled attribute
+
+;; mov:   ISA has no MOVW
+;; movw:  ISA has MOVW
+;; rjmp:  ISA has no CALL/JMP
+;; jmp:   ISA has CALL/JMP
+;; ijmp:  ISA has no EICALL/EIJMP
+;; eijmp: ISA has EICALL/EIJMP
+
+(define_attr "isa"
+  "mov,movw, rjmp,jmp, ijmp,eijmp,
+   standard"
+  (const_string "standard"))
+
+(define_attr "enabled" ""
+  (cond [(eq_attr "isa" "standard")
+         (const_int 1)
+         
+         (and (eq_attr "isa" "mov")
+              (match_test "!AVR_HAVE_MOVW"))
+         (const_int 1)
+
+         (and (eq_attr "isa" "movw")
+              (match_test "AVR_HAVE_MOVW"))
+         (const_int 1)
+         
+         (and (eq_attr "isa" "rjmp")
+              (match_test "!AVR_HAVE_JMP_CALL"))
+         (const_int 1)
+
+         (and (eq_attr "isa" "jmp")
+              (match_test "AVR_HAVE_JMP_CALL"))
+         (const_int 1)
+         
+         (and (eq_attr "isa" "ijmp")
+              (match_test "!AVR_HAVE_EIJMP_EICALL"))
+         (const_int 1)
+
+         (and (eq_attr "isa" "eijmp")
+              (match_test "AVR_HAVE_EIJMP_EICALL"))
+         (const_int 1)
+         ] (const_int 0)))
+
+
 ;; Define mode iterators
 (define_mode_iterator QIHI  [(QI "") (HI "")])
 (define_mode_iterator QIHI2 [(QI "") (HI "")])
@@ -2949,20 +2981,17 @@  (define_insn "neghi2"
    (set_attr "cc" "set_czn,set_n,set_czn")])
 
 (define_insn "negsi2"
-  [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r")
-	(neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
+  [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r,&r")
+        (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
   ""
   "@
 	com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
 	com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
-	clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
-  [(set_attr_alternative "length"
-			 [(const_int 7)
-			  (const_int 8)
-			  (if_then_else (eq_attr "mcu_have_movw" "yes")
-					(const_int 7)
-					(const_int 8))])
-   (set_attr "cc" "set_czn,set_n,set_czn")])
+	clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
+	clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
+  [(set_attr "length" "7,8,8,7")
+   (set_attr "isa"    "*,*,mov,movw")
+   (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
 
 (define_insn "negsf2"
   [(set (match_operand:SF 0 "register_operand" "=d,r")
@@ -3036,18 +3065,16 @@  (define_insn "extendqisi2"
    (set_attr "cc" "set_n,set_n")])
 
 (define_insn "extendhisi2"
-  [(set (match_operand:SI 0 "register_operand"                               "=r,r")
-        (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
+  [(set (match_operand:SI 0 "register_operand"                               "=r,r ,r")
+        (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
   ""
   "@
 	clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
-	{mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
-  [(set_attr_alternative "length"
-			 [(const_int 4)
-			  (if_then_else (eq_attr "mcu_have_movw" "yes")
-					(const_int 5)
-					(const_int 6))])
-   (set_attr "cc" "set_n,set_n")])
+	mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
+	movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
+  [(set_attr "length" "4,6,5")
+   (set_attr "isa" "*,mov,movw")
+   (set_attr "cc" "set_n")])
 
 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
 ;; zero extend
@@ -3356,7 +3383,7 @@  (define_insn "*sbrx_branch<mode>"
 	(if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
 			   (le (minus (pc) (match_dup 3)) (const_int 2046)))
 		      (const_int 2)
-		      (if_then_else (eq_attr "mcu_mega" "no")
+		      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
 				    (const_int 2)
 				    (const_int 4))))
    (set_attr "cc" "clobber")])
@@ -3386,7 +3413,7 @@  (define_insn "*sbrx_and_branch<mode>"
 	(if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
 			   (le (minus (pc) (match_dup 3)) (const_int 2046)))
 		      (const_int 2)
-		      (if_then_else (eq_attr "mcu_mega" "no")
+		      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
 				    (const_int 2)
 				    (const_int 4))))
    (set_attr "cc" "clobber")])
@@ -3569,20 +3596,24 @@  (define_insn "jump"
   [(set (pc)
         (label_ref (match_operand 0 "" "")))]
   ""
-  "*{
-  if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
-    return AS1 (jmp,%x0);
-  return AS1 (rjmp,%x0);
-}"
+  {
+    return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
+           ? "jmp %x0"
+           : "rjmp %x0";
+  }
   [(set (attr "length")
 	(if_then_else (match_operand 0 "symbol_ref_operand" "")	
-		(if_then_else (eq_attr "mcu_mega" "no")
-			      (const_int 1)
-			      (const_int 2))
-		(if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
-				   (le (minus (pc) (match_dup 0)) (const_int 2047)))
-			      (const_int 1)
-			      (const_int 2))))
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
+                                    (const_int 1)
+                                    (const_int 2))
+                      (if_then_else (and (ge (minus (pc)
+                                                    (match_dup 0))
+                                             (const_int -2047))
+                                         (le (minus (pc)
+                                                    (match_dup 0))
+                                             (const_int 2047)))
+                                    (const_int 1)
+                                    (const_int 2))))
    (set_attr "cc" "none")])
 
 ;; call
@@ -3640,15 +3671,8 @@  (define_insn "call_insn"
     %!ijmp
     %~jmp %x0"
   [(set_attr "cc" "clobber")
-   (set_attr_alternative "length"
-                         [(const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))
-                          (const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))])])
+   (set_attr "length" "1,*,1,*")
+   (set_attr "adjust_len" "*,call,*,call")])
 
 (define_insn "call_value_insn"
   [(parallel[(set (match_operand 0 "register_operand"                   "=r,r,r,r")
@@ -3664,15 +3688,8 @@  (define_insn "call_value_insn"
     %!ijmp
     %~jmp %x1"
   [(set_attr "cc" "clobber")
-   (set_attr_alternative "length"
-                         [(const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))
-                          (const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))])])
+   (set_attr "length" "1,*,1,*")
+   (set_attr "adjust_len" "*,call,*,call")])
 
 (define_insn "nop"
   [(const_int 0)]
@@ -3684,69 +3701,51 @@  (define_insn "nop"
 ; indirect jump
 
 (define_expand "indirect_jump"
-  [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
+  [(set (pc)
+        (match_operand:HI 0 "nonmemory_operand" ""))]
   ""
-  " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
-    {
-      operands[0] = copy_to_mode_reg(HImode, operand0);
-    }"
-)
+  {
+    if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
+      {
+        operands[0] = copy_to_mode_reg (HImode, operands[0]);
+      }
+  })
 
 ; indirect jump
-(define_insn "*jcindirect_jump"
-  [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
+(define_insn "*indirect_jump"
+  [(set (pc)
+        (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
   ""
-  "%~jmp %x0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "none")])
-
-;;
-(define_insn "*njcindirect_jump"
-  [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
-  "!AVR_HAVE_EIJMP_EICALL"
   "@
+	rjmp %x0
+	jmp %x0
 	ijmp
-	push %A0\;push %B0\;ret"
-  [(set_attr "length" "1,3")
-   (set_attr "cc" "none,none")])
-
-(define_insn "*indirect_jump_avr6"
-  [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
-  "AVR_HAVE_EIJMP_EICALL"
-  "eijmp"
-  [(set_attr "length" "1")
+	push %A0\;push %B0\;ret
+	eijmp"
+  [(set_attr "length" "1,2,1,3,1")
+   (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
    (set_attr "cc" "none")])
 
 ;; table jump
 ;; For entries in jump table see avr_output_addr_vec_elt.
 
-;; Table made from "rjmp .L<n>" instructions for <= 8K devices.
-(define_insn "*tablejump_rjmp"
+;; Table made from
+;;    "rjmp .L<n>"   instructions for <= 8K devices
+;;    ".word gs(.L<n>)" addresses for >  8K devices
+(define_insn "*tablejump"
   [(set (pc)
-        (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
+        (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
                    UNSPEC_INDEX_JMP))
    (use (label_ref (match_operand 1 "" "")))
    (clobber (match_dup 0))]
-  "!AVR_HAVE_JMP_CALL"
+  ""
   "@
 	ijmp
-	push %A0\;push %B0\;ret"
-  [(set_attr "length" "1,3")
-   (set_attr "cc" "none,none")])
-
-;; Move the common piece of code to libgcc.
-;; Table made from ".word gs(.L<n>)" addresses for > 8K devices.
-;; Read jump address from table and perform indirect jump.
-(define_insn "*tablejump_lib"
-  [(set (pc)
-        (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
-                   UNSPEC_INDEX_JMP))
-   (use (label_ref (match_operand 1 "" "")))
-   (clobber (match_dup 0))]
-  "AVR_HAVE_JMP_CALL"
-  "jmp __tablejump2__"
-  [(set_attr "length" "2")
-   (set_attr "cc" "clobber")])
+	push %A0\;push %B0\;ret
+	jmp __tablejump2__"
+  [(set_attr "length" "1,3,2")
+   (set_attr "isa" "rjmp,rjmp,jmp")
+   (set_attr "cc" "none,none,clobber")])
 
 
 (define_expand "casesi"
@@ -3829,11 +3828,11 @@  (define_insn "*sbix_branch"
   "* return avr_out_sbxx_branch (insn, operands);"
   [(set (attr "length")
 	(if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
-			   (le (minus (pc) (match_dup 3)) (const_int 2046)))
-		      (const_int 2)
-		      (if_then_else (eq_attr "mcu_mega" "no")
-				    (const_int 2)
-				    (const_int 4))))
+                           (le (minus (pc) (match_dup 3)) (const_int 2046)))
+                      (const_int 2)
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
+                                    (const_int 2)
+                                    (const_int 4))))
    (set_attr "cc" "clobber")])
 
 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
@@ -3853,11 +3852,11 @@  (define_insn "*sbix_branch_bit7"
 }
   [(set (attr "length")
 	(if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
-			   (le (minus (pc) (match_dup 2)) (const_int 2046)))
-		      (const_int 2)
-		      (if_then_else (eq_attr "mcu_mega" "no")
-				    (const_int 2)
-				    (const_int 4))))
+                           (le (minus (pc) (match_dup 2)) (const_int 2046)))
+                      (const_int 2)
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
+                                    (const_int 2)
+                                    (const_int 4))))
    (set_attr "cc" "clobber")])
 
 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
@@ -3876,11 +3875,11 @@  (define_insn "*sbix_branch_tmp"
   "* return avr_out_sbxx_branch (insn, operands);"
   [(set (attr "length")
 	(if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
-			   (le (minus (pc) (match_dup 3)) (const_int 2045)))
-		      (const_int 3)
-		      (if_then_else (eq_attr "mcu_mega" "no")
-				    (const_int 3)
-				    (const_int 5))))
+                           (le (minus (pc) (match_dup 3)) (const_int 2045)))
+                      (const_int 3)
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
+                                    (const_int 3)
+                                    (const_int 5))))
    (set_attr "cc" "clobber")])
 
 (define_insn "*sbix_branch_tmp_bit7"
@@ -3901,7 +3900,7 @@  (define_insn "*sbix_branch_tmp_bit7"
 	(if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
 			   (le (minus (pc) (match_dup 2)) (const_int 2045)))
 		      (const_int 3)
-		      (if_then_else (eq_attr "mcu_mega" "no")
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
 				    (const_int 3)
 				    (const_int 5))))
    (set_attr "cc" "clobber")])
@@ -4064,10 +4063,10 @@  (define_insn "disable_interrupt"
 ;;  Library prologue saves
 (define_insn "call_prologue_saves"
   [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
-   (match_operand:HI 0 "immediate_operand" "")
-   (set (reg:HI REG_SP) (minus:HI 
-                           (reg:HI REG_SP)
-                           (match_operand:HI 1 "immediate_operand" "")))
+   (match_operand:HI 0 "immediate_operand" "i,i")
+   (set (reg:HI REG_SP)
+        (minus:HI (reg:HI REG_SP)
+                  (match_operand:HI 1 "immediate_operand" "i,i")))
    (use (reg:HI REG_X))
    (clobber (reg:HI REG_Z))]
   ""
@@ -4075,30 +4074,26 @@  (define_insn "call_prologue_saves"
 	ldi r31,hi8(gs(1f))
 	%~jmp __prologue_saves__+((18 - %0) * 2)
 1:"
-  [(set_attr_alternative "length"
-			 [(if_then_else (eq_attr "mcu_mega" "yes")
-					(const_int 6)
-					(const_int 5))])
-  (set_attr "cc" "clobber")
-  ])
+  [(set_attr "length" "5,6")
+   (set_attr "isa" "rjmp,jmp")
+   (set_attr "cc" "clobber")])
   
 ;  epilogue  restores using library
 (define_insn "epilogue_restores"
   [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
-   (set (reg:HI REG_Y ) (plus:HI 
-                           (reg:HI REG_Y)
-                           (match_operand:HI 0 "immediate_operand" ""))) 
-   (set (reg:HI REG_SP) (reg:HI REG_Y))
-   (clobber  (reg:QI REG_Z))]
+   (set (reg:HI REG_Y)
+        (plus:HI (reg:HI REG_Y)
+                 (match_operand:HI 0 "immediate_operand" "i,i")))
+   (set (reg:HI REG_SP)
+        (plus:HI (reg:HI REG_Y)
+                 (match_dup 0)))
+   (clobber (reg:QI REG_Z))]
   ""
   "ldi r30, lo8(%0)
 	%~jmp __epilogue_restores__ + ((18 - %0) * 2)"
-  [(set_attr_alternative "length"
-			 [(if_then_else (eq_attr "mcu_mega" "yes")
-					(const_int 3)
-					(const_int 2))])
-  (set_attr "cc" "clobber")
-  ])
+  [(set_attr "length" "2,3")
+   (set_attr "isa" "rjmp,jmp")
+   (set_attr "cc" "clobber")])
   
 ; return
 (define_insn "return"
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 180076)
+++ config/avr/avr.c	(working copy)
@@ -5331,6 +5331,8 @@  adjust_insn_length (rtx insn, int len)
     case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
     case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
       
+    case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
+
     default:
       gcc_unreachable();
     }
Index: config/avr/avr.h
===================================================================
--- config/avr/avr.h	(revision 180076)
+++ config/avr/avr.h	(working copy)
@@ -454,8 +454,6 @@  typedef struct avr_args {
 
 #define PRINT_OPERAND_ADDRESS(STREAM, X) print_operand_address(STREAM, X)
 
-#define ASSEMBLER_DIALECT AVR_HAVE_MOVW
-
 #define ASM_OUTPUT_REG_PUSH(STREAM, REGNO)	\
 {						\
   gcc_assert (REGNO < 32);			\