summaryrefslogtreecommitdiffstats
path: root/libgcc
diff options
context:
space:
mode:
authorgjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-11 08:19:45 +0000
committergjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-11 08:19:45 +0000
commitb82aef210d119f14c65ca0bb45e584aa46450e3f (patch)
tree408889137b21fa5b2648b3d868609487da945739 /libgcc
parent8d32cc6303ae6f9bac7418305f30b2869aab4088 (diff)
downloadppe42-gcc-b82aef210d119f14c65ca0bb45e584aa46450e3f.tar.gz
ppe42-gcc-b82aef210d119f14c65ca0bb45e584aa46450e3f.zip
gcc/
Backport from 2014-09-11 trunk r215152. PR target/63223 * config/avr/avr.md (*tablejump.3byte-pc): New insn. (*tablejump): Restrict to !AVR_HAVE_EIJMP_EICALL. Add void clobber. (casesi): Expand to *tablejump.3byte-pc if AVR_HAVE_EIJMP_EICALL. libgcc/ Backport from 2014-09-11 trunk r215152. PR target/63223 * config/avr/libgcc.S (__tablejump2__): Rewrite to use RAMPZ, ELPM and R24 as needed. Make work for all devices and .text locations. (__do_global_ctors, __do_global_dtors): Use word addresses. (__tablejump__, __tablejump_elpm__): Remove functions. * t-avr (LIB1ASMFUNCS): Remove _tablejump, _tablejump_elpm. Add _tablejump2. (XICALL, XIJMP): New macros. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@215153 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog13
-rw-r--r--libgcc/config/avr/lib1funcs.S227
-rw-r--r--libgcc/config/avr/t-avr3
3 files changed, 114 insertions, 129 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 3bc241c3dae..8f7094d345d 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,16 @@
+2014-09-11 Georg-Johann Lay <avr@gjlay.de>
+
+ Backport from 2014-09-11 trunk r215152.
+
+ PR target/63223
+ * config/avr/libgcc.S (__tablejump2__): Rewrite to use RAMPZ, ELPM
+ and R24 as needed. Make work for all devices and .text locations.
+ (__do_global_ctors, __do_global_dtors): Use word addresses.
+ (__tablejump__, __tablejump_elpm__): Remove functions.
+ * t-avr (LIB1ASMFUNCS): Remove _tablejump, _tablejump_elpm.
+ Add _tablejump2.
+ (XICALL, XIJMP): New macros.
+
2014-08-04 Rohit <rohitarulraj@freescale.com>
PR target/60102
diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S
index 6f1c77edbe3..080e250cd61 100644
--- a/libgcc/config/avr/lib1funcs.S
+++ b/libgcc/config/avr/lib1funcs.S
@@ -46,6 +46,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
input sections together are small enough to reach every
location with a RCALL/RJMP instruction. */
+#if defined (__AVR_HAVE_EIJMP_EICALL__) && !defined (__AVR_HAVE_ELPMX__)
+#error device not supported
+#endif
+
.macro mov_l r_dest, r_src
#if defined (__AVR_HAVE_MOVW__)
movw \r_dest, \r_src
@@ -79,6 +83,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define XJMP rjmp
#endif
+#if defined (__AVR_HAVE_EIJMP_EICALL__)
+#define XICALL eicall
+#define XIJMP eijmp
+#else
+#define XICALL icall
+#define XIJMP ijmp
+#endif
+
;; Prologue stuff
.macro do_prologue_saves n_pushed n_frame=0
@@ -2127,11 +2139,7 @@ DEFUN __prologue_saves__
out __SP_L__,r28
#endif /* #SP = 8/16 */
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
- eijmp
-#else
- ijmp
-#endif
+ XIJMP
ENDF __prologue_saves__
#endif /* defined (L_prologue) */
@@ -2213,38 +2221,54 @@ _cleanup:
.section .text.libgcc, "ax", @progbits
-#ifdef L_tablejump
+#ifdef L_tablejump2
DEFUN __tablejump2__
- lsl r30
- rol r31
- ;; FALLTHRU
-ENDF __tablejump2__
-
-DEFUN __tablejump__
-#if defined (__AVR_HAVE_LPMX__)
- lpm __tmp_reg__, Z+
- lpm r31, Z
- mov r30, __tmp_reg__
+ lsl r30
+ rol r31
#if defined (__AVR_HAVE_EIJMP_EICALL__)
- eijmp
-#else
- ijmp
+ ;; Word address of gs() jumptable entry in R24:Z
+ rol r24
+ out __RAMPZ__, r24
+#elif defined (__AVR_HAVE_ELPM__)
+ ;; Word address of jumptable entry in Z
+ clr __tmp_reg__
+ rol __tmp_reg__
+ out __RAMPZ__, __tmp_reg__
#endif
-#else /* !HAVE_LPMX */
- lpm
- adiw r30, 1
- push r0
- lpm
- push r0
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
- in __tmp_reg__, __EIND__
- push __tmp_reg__
+ ;; Read word address from jumptable and jump
+
+#if defined (__AVR_HAVE_ELPMX__)
+ elpm __tmp_reg__, Z+
+ elpm r31, Z
+ mov r30, __tmp_reg__
+#ifdef __AVR_HAVE_RAMPD__
+ ;; Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM
+ out __RAMPZ__, __zero_reg__
+#endif /* RAMPD */
+ XIJMP
+#elif defined (__AVR_HAVE_ELPM__)
+ elpm
+ push r0
+ adiw r30, 1
+ elpm
+ push r0
+ ret
+#elif defined (__AVR_HAVE_LPMX__)
+ lpm __tmp_reg__, Z+
+ lpm r31, Z
+ mov r30, __tmp_reg__
+ ijmp
+#else
+ lpm
+ push r0
+ adiw r30, 1
+ lpm
+ push r0
+ ret
#endif
- ret
-#endif /* !HAVE_LPMX */
-ENDF __tablejump__
-#endif /* defined (L_tablejump) */
+ENDF __tablejump2__
+#endif /* L_tablejump2 */
#ifdef L_copy_data
.section .init4,"ax",@progbits
@@ -2336,116 +2360,65 @@ ENDF __do_clear_bss
#ifdef L_ctors
.section .init6,"ax",@progbits
DEFUN __do_global_ctors
-#if defined(__AVR_HAVE_ELPM__)
- ldi r17, hi8(__ctors_start)
- ldi r28, lo8(__ctors_end)
- ldi r29, hi8(__ctors_end)
- ldi r16, hh8(__ctors_end)
- rjmp .L__do_global_ctors_start
+ ldi r17, pm_hi8(__ctors_start)
+ ldi r28, pm_lo8(__ctors_end)
+ ldi r29, pm_hi8(__ctors_end)
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ ldi r16, pm_hh8(__ctors_end)
+#endif /* HAVE_EIJMP */
+ rjmp .L__do_global_ctors_start
.L__do_global_ctors_loop:
- sbiw r28, 2
- sbc r16, __zero_reg__
- mov_h r31, r29
- mov_l r30, r28
- out __RAMPZ__, r16
- XCALL __tablejump_elpm__
+ sbiw r28, 1
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ sbc r16, __zero_reg__
+ mov r24, r16
+#endif /* HAVE_EIJMP */
+ mov_h r31, r29
+ mov_l r30, r28
+ XCALL __tablejump2__
.L__do_global_ctors_start:
- cpi r28, lo8(__ctors_start)
- cpc r29, r17
- ldi r24, hh8(__ctors_start)
- cpc r16, r24
- brne .L__do_global_ctors_loop
-#else
- ldi r17, hi8(__ctors_start)
- ldi r28, lo8(__ctors_end)
- ldi r29, hi8(__ctors_end)
- rjmp .L__do_global_ctors_start
-.L__do_global_ctors_loop:
- sbiw r28, 2
- mov_h r31, r29
- mov_l r30, r28
- XCALL __tablejump__
-.L__do_global_ctors_start:
- cpi r28, lo8(__ctors_start)
- cpc r29, r17
- brne .L__do_global_ctors_loop
-#endif /* defined(__AVR_HAVE_ELPM__) */
+ cpi r28, pm_lo8(__ctors_start)
+ cpc r29, r17
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ ldi r24, pm_hh8(__ctors_start)
+ cpc r16, r24
+#endif /* HAVE_EIJMP */
+ brne .L__do_global_ctors_loop
ENDF __do_global_ctors
#endif /* L_ctors */
#ifdef L_dtors
.section .fini6,"ax",@progbits
DEFUN __do_global_dtors
-#if defined(__AVR_HAVE_ELPM__)
- ldi r17, hi8(__dtors_end)
- ldi r28, lo8(__dtors_start)
- ldi r29, hi8(__dtors_start)
- ldi r16, hh8(__dtors_start)
- rjmp .L__do_global_dtors_start
+ ldi r17, pm_hi8(__dtors_start)
+ ldi r28, pm_lo8(__dtors_end)
+ ldi r29, pm_hi8(__dtors_end)
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ ldi r16, pm_hh8(__dtors_end)
+#endif /* HAVE_EIJMP */
+ rjmp .L__do_global_dtors_start
.L__do_global_dtors_loop:
- sbiw r28, 2
- sbc r16, __zero_reg__
- mov_h r31, r29
- mov_l r30, r28
- out __RAMPZ__, r16
- XCALL __tablejump_elpm__
+ sbiw r28, 1
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ sbc r16, __zero_reg__
+ mov r24, r16
+#endif /* HAVE_EIJMP */
+ mov_h r31, r29
+ mov_l r30, r28
+ XCALL __tablejump2__
.L__do_global_dtors_start:
- cpi r28, lo8(__dtors_end)
- cpc r29, r17
- ldi r24, hh8(__dtors_end)
- cpc r16, r24
- brne .L__do_global_dtors_loop
-#else
- ldi r17, hi8(__dtors_end)
- ldi r28, lo8(__dtors_start)
- ldi r29, hi8(__dtors_start)
- rjmp .L__do_global_dtors_start
-.L__do_global_dtors_loop:
- mov_h r31, r29
- mov_l r30, r28
- XCALL __tablejump__
- adiw r28, 2
-.L__do_global_dtors_start:
- cpi r28, lo8(__dtors_end)
- cpc r29, r17
- brne .L__do_global_dtors_loop
-#endif /* defined(__AVR_HAVE_ELPM__) */
+ cpi r28, pm_lo8(__dtors_start)
+ cpc r29, r17
+#ifdef __AVR_HAVE_EIJMP_EICALL__
+ ldi r24, pm_hh8(__dtors_start)
+ cpc r16, r24
+#endif /* HAVE_EIJMP */
+ brne .L__do_global_dtors_loop
ENDF __do_global_dtors
#endif /* L_dtors */
.section .text.libgcc, "ax", @progbits
-#ifdef L_tablejump_elpm
-DEFUN __tablejump_elpm__
-#if defined (__AVR_HAVE_ELPMX__)
- elpm __tmp_reg__, Z+
- elpm r31, Z
- mov r30, __tmp_reg__
-#if defined (__AVR_HAVE_RAMPD__)
- ;; Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM
- out __RAMPZ__, __zero_reg__
-#endif /* RAMPD */
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
- eijmp
-#else
- ijmp
-#endif
-
-#elif defined (__AVR_HAVE_ELPM__)
- elpm
- adiw r30, 1
- push r0
- elpm
- push r0
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
- in __tmp_reg__, __EIND__
- push __tmp_reg__
-#endif
- ret
-#endif
-ENDF __tablejump_elpm__
-#endif /* defined (L_tablejump_elpm) */
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loading n bytes from Flash; n = 3,4
;; R22... = Flash[Z]
diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr
index 461304706d9..1f7356968aa 100644
--- a/libgcc/config/avr/t-avr
+++ b/libgcc/config/avr/t-avr
@@ -26,8 +26,7 @@ LIB1ASMFUNCS = \
_epilogue \
_exit \
_cleanup \
- _tablejump \
- _tablejump_elpm \
+ _tablejump2 \
_load_3 _load_4 \
_xload_1 _xload_2 _xload_3 _xload_4 \
_movmemx \
OpenPOWER on IntegriCloud