From 917e14f3d2781c8b4e3b944313e9b9ef3af77425 Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Mon, 10 Oct 2011 16:31:22 +0000 Subject: avr.md (*tablejump_rjmp): Change insn condition to !AVR_HAVE_JMP_CALL. * 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. From-SVN: r179760 --- gcc/config/avr/avr.md | 54 +++++++++++++------------------------------------ gcc/config/avr/libgcc.S | 28 ++++++++++++++----------- 2 files changed, 30 insertions(+), 52 deletions(-) (limited to 'gcc/config') 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) */ -- cgit v1.1