aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2011-10-10 16:31:22 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2011-10-10 16:31:22 +0000
commit917e14f3d2781c8b4e3b944313e9b9ef3af77425 (patch)
treeffecb19b863e52143490a6831033857e839edbc2 /gcc/config/avr
parent82675d94dedc9b052cf83b7d028b5c25786c2cfa (diff)
downloadgcc-917e14f3d2781c8b4e3b944313e9b9ef3af77425.zip
gcc-917e14f3d2781c8b4e3b944313e9b9ef3af77425.tar.gz
gcc-917e14f3d2781c8b4e3b944313e9b9ef3af77425.tar.bz2
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
Diffstat (limited to 'gcc/config/avr')
-rw-r--r--gcc/config/avr/avr.md54
-rw-r--r--gcc/config/avr/libgcc.S28
2 files changed, 30 insertions, 52 deletions
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<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)
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) */