From 96fc2c797cd66487561fc6fe7f7770ed9d111068 Mon Sep 17 00:00:00 2001 From: gjl Date: Mon, 10 Oct 2011 16:31:22 +0000 Subject: [PATCH] * config/avr/avr.md (*tablejump_rjmp): Change insn condition to !AVR_HAVE_JMP_CALL. (*tablejump_lib): Change insn condition to AVR_HAVE_JMP_CALL. (*tablejump_enh, *tablejump): Remove insns. * config/avr/libgcc.S (__tablejump__): Use RET instead of EIND + EIJMP for indirect jump. Use LPM Z+ where available. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179760 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 +++++++++ gcc/config/avr/avr.md | 54 +++++++++++++------------------------------------ gcc/config/avr/libgcc.S | 28 ++++++++++++++----------- 3 files changed, 39 insertions(+), 52 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2925ee2..358c557 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-10-10 Georg-Johann Lay + + * config/avr/avr.md (*tablejump_rjmp): Change insn condition to + !AVR_HAVE_JMP_CALL. + (*tablejump_lib): Change insn condition to AVR_HAVE_JMP_CALL. + (*tablejump_enh, *tablejump): Remove insns. + * config/avr/libgcc.S (__tablejump__): Use RET instead of EIND + + EIJMP for indirect jump. Use LPM Z+ where available. + 2011-10-10 Richard Henderson * doc/md.texi (vec_perm_const): Fix typo in cindex. diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index e17f7f2..23541bf 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -3719,62 +3719,36 @@ (set_attr "cc" "none")]) ;; table jump +;; For entries in jump table see avr_output_addr_vec_elt. -;; Table made from "rjmp" instructions for <=8K devices. +;; Table made from "rjmp .L" instructions for <= 8K devices. (define_insn "*tablejump_rjmp" - [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] - UNSPEC_INDEX_JMP)) + [(set (pc) + (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] + UNSPEC_INDEX_JMP)) (use (label_ref (match_operand 1 "" ""))) (clobber (match_dup 0))] - "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)" + "!AVR_HAVE_JMP_CALL" "@ ijmp push %A0\;push %B0\;ret" [(set_attr "length" "1,3") (set_attr "cc" "none,none")]) -;; Not a prologue, but similar idea - move the common piece of code to libgcc. +;; Move the common piece of code to libgcc. +;; Table made from ".word gs(.L)" 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)) + [(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 && TARGET_CALL_PROLOGUES" - "%~jmp __tablejump2__" + "AVR_HAVE_JMP_CALL" + "jmp __tablejump2__" [(set_attr "length" "2") (set_attr "cc" "clobber")]) -(define_insn "*tablejump_enh" - [(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 && AVR_HAVE_LPMX" - "lsl r30 - rol r31 - lpm __tmp_reg__,Z+ - lpm r31,Z - mov r30,__tmp_reg__ - %!ijmp" - [(set_attr "length" "6") - (set_attr "cc" "clobber")]) - -(define_insn "*tablejump" - [(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 && !AVR_HAVE_EIJMP_EICALL" - "lsl r30 - rol r31 - lpm - inc r30 - push r0 - lpm - push r0 - ret" - [(set_attr "length" "8") - (set_attr "cc" "clobber")]) (define_expand "casesi" [(set (match_dup 6) diff --git a/gcc/config/avr/libgcc.S b/gcc/config/avr/libgcc.S index a4e4b42..8df3607 100644 --- a/gcc/config/avr/libgcc.S +++ b/gcc/config/avr/libgcc.S @@ -821,27 +821,31 @@ ENDF __tablejump2__ DEFUN __tablejump__ #if defined (__AVR_HAVE_LPMX__) - lpm __tmp_reg__, Z+ - lpm r31, Z - mov r30, __tmp_reg__ - #if defined (__AVR_HAVE_EIJMP_EICALL__) - eijmp -#else + lpm __tmp_reg__, Z+ + push __tmp_reg__ + lpm __tmp_reg__, Z + push __tmp_reg__ + push __zero_reg__ + ret +#else + lpm __tmp_reg__, Z+ + lpm r31, Z + mov r30, __tmp_reg__ ijmp #endif -#else +#else /* !HAVE_LPMX */ lpm - adiw r30, 1 - push r0 + adiw r30, 1 + push r0 lpm - push r0 + push r0 #if defined (__AVR_HAVE_EIJMP_EICALL__) - push __zero_reg__ + push __zero_reg__ #endif ret -#endif +#endif /* !HAVE_LPMX */ ENDF __tablejump__ #endif /* defined (L_tablejump) */ -- 2.7.4