avr.md (*tablejump_rjmp): Change insn condition to !AVR_HAVE_JMP_CALL.
authorGeorg-Johann Lay <avr@gjlay.de>
Mon, 10 Oct 2011 16:31:22 +0000 (16:31 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Mon, 10 Oct 2011 16:31:22 +0000 (16:31 +0000)
* 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/ChangeLog
gcc/config/avr/avr.md
gcc/config/avr/libgcc.S

index 2925ee259d4a30ff8cdea29fd2de80a0e243a036..358c5571257647dc405575ca7caf33b89e15bcf1 100644 (file)
@@ -1,3 +1,12 @@
+2011-10-10  Georg-Johann Lay  <avr@gjlay.de>
+
+       * 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  <rth@redhat.com>
 
        * doc/md.texi (vec_perm_const): Fix typo in cindex.
index e17f7f2f2638a349fa95d0b7c8bc977a561a3aa8..23541bf9d2c50c92142e9a3aff3b82e48a914414 100644 (file)
    (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<n>" 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<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))
+  [(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)
index a4e4b4215b5250915c93b3e7d5e49b481033de37..8df3607237042092dd07ca7373a86e3bf0d87f0d 100644 (file)
@@ -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) */