Commit ea3f2b24 by Georg-Johann Lay Committed by Georg-Johann Lay

re PR target/63223 ([avr] Make jumptables work with -Wl,--section-start,.text=)

gcc/
	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/
	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.

From-SVN: r215152
parent c883e5fb
2014-09-11 Georg-Johann Lay <avr@gjlay.de>
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.
2014-09-11 Alexander Ivchenko <alexander.ivchenko@intel.com> 2014-09-11 Alexander Ivchenko <alexander.ivchenko@intel.com>
Maxim Kuznetsov <maxim.kuznetsov@intel.com> Maxim Kuznetsov <maxim.kuznetsov@intel.com>
Anna Tikhonova <anna.tikhonova@intel.com> Anna Tikhonova <anna.tikhonova@intel.com>
...@@ -4932,8 +4932,9 @@ ...@@ -4932,8 +4932,9 @@
(unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")] (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
UNSPEC_INDEX_JMP)) UNSPEC_INDEX_JMP))
(use (label_ref (match_operand 1 "" ""))) (use (label_ref (match_operand 1 "" "")))
(clobber (match_dup 0))] (clobber (match_dup 0))
"" (clobber (const_int 0))]
"!AVR_HAVE_EIJMP_EICALL"
"@ "@
ijmp ijmp
push %A0\;push %B0\;ret push %A0\;push %B0\;ret
...@@ -4942,6 +4943,19 @@ ...@@ -4942,6 +4943,19 @@
(set_attr "isa" "rjmp,rjmp,jmp") (set_attr "isa" "rjmp,rjmp,jmp")
(set_attr "cc" "none,none,clobber")]) (set_attr "cc" "none,none,clobber")])
(define_insn "*tablejump.3byte-pc"
[(set (pc)
(unspec:HI [(reg:HI REG_Z)]
UNSPEC_INDEX_JMP))
(use (label_ref (match_operand 0 "" "")))
(clobber (reg:HI REG_Z))
(clobber (reg:QI 24))]
"AVR_HAVE_EIJMP_EICALL"
"clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__"
[(set_attr "length" "6")
(set_attr "isa" "eijmp")
(set_attr "cc" "clobber")])
(define_expand "casesi" (define_expand "casesi"
[(parallel [(set (match_dup 6) [(parallel [(set (match_dup 6)
...@@ -4959,15 +4973,31 @@ ...@@ -4959,15 +4973,31 @@
(label_ref (match_operand 4 "" "")) (label_ref (match_operand 4 "" ""))
(pc))) (pc)))
(set (match_dup 6) (set (match_dup 10)
(plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" "")))) (match_dup 7))
(parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP)) (parallel [(set (pc)
(unspec:HI [(match_dup 10)] UNSPEC_INDEX_JMP))
(use (label_ref (match_dup 3))) (use (label_ref (match_dup 3)))
(clobber (match_dup 6))])] (clobber (match_dup 10))
(clobber (match_dup 8))])]
"" ""
{ {
operands[6] = gen_reg_rtx (HImode); operands[6] = gen_reg_rtx (HImode);
if (AVR_HAVE_EIJMP_EICALL)
{
operands[7] = operands[6];
operands[8] = all_regs_rtx[24];
operands[10] = gen_rtx_REG (HImode, REG_Z);
}
else
{
operands[7] = gen_rtx_PLUS (HImode, operands[6],
gen_rtx_LABEL_REF (VOIDmode, operands[3]));
operands[8] = const0_rtx;
operands[10] = operands[6];
}
}) })
......
2014-09-11 Georg-Johann Lay <avr@gjlay.de>
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-09-09 Marcus Shawcroft <marcus.shawcroft@arm.com> 2014-09-09 Marcus Shawcroft <marcus.shawcroft@arm.com>
Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
......
...@@ -46,6 +46,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -46,6 +46,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
input sections together are small enough to reach every input sections together are small enough to reach every
location with a RCALL/RJMP instruction. */ 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 .macro mov_l r_dest, r_src
#if defined (__AVR_HAVE_MOVW__) #if defined (__AVR_HAVE_MOVW__)
movw \r_dest, \r_src movw \r_dest, \r_src
...@@ -79,6 +83,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -79,6 +83,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define XJMP rjmp #define XJMP rjmp
#endif #endif
#if defined (__AVR_HAVE_EIJMP_EICALL__)
#define XICALL eicall
#define XIJMP eijmp
#else
#define XICALL icall
#define XIJMP ijmp
#endif
;; Prologue stuff ;; Prologue stuff
.macro do_prologue_saves n_pushed n_frame=0 .macro do_prologue_saves n_pushed n_frame=0
...@@ -2127,11 +2139,7 @@ DEFUN __prologue_saves__ ...@@ -2127,11 +2139,7 @@ DEFUN __prologue_saves__
out __SP_L__,r28 out __SP_L__,r28
#endif /* #SP = 8/16 */ #endif /* #SP = 8/16 */
#if defined (__AVR_HAVE_EIJMP_EICALL__) XIJMP
eijmp
#else
ijmp
#endif
ENDF __prologue_saves__ ENDF __prologue_saves__
#endif /* defined (L_prologue) */ #endif /* defined (L_prologue) */
...@@ -2213,38 +2221,54 @@ _cleanup: ...@@ -2213,38 +2221,54 @@ _cleanup:
.section .text.libgcc, "ax", @progbits .section .text.libgcc, "ax", @progbits
#ifdef L_tablejump #ifdef L_tablejump2
DEFUN __tablejump2__ DEFUN __tablejump2__
lsl r30 lsl r30
rol r31 rol r31
;; FALLTHRU #if defined (__AVR_HAVE_EIJMP_EICALL__)
ENDF __tablejump2__ ;; 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
DEFUN __tablejump__ ;; Read word address from jumptable and jump
#if defined (__AVR_HAVE_LPMX__)
#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 __tmp_reg__, Z+
lpm r31, Z lpm r31, Z
mov r30, __tmp_reg__ mov r30, __tmp_reg__
#if defined (__AVR_HAVE_EIJMP_EICALL__)
eijmp
#else
ijmp ijmp
#endif #else
#else /* !HAVE_LPMX */
lpm lpm
adiw r30, 1
push r0 push r0
adiw r30, 1
lpm lpm
push r0 push r0
#if defined (__AVR_HAVE_EIJMP_EICALL__)
in __tmp_reg__, __EIND__
push __tmp_reg__
#endif
ret ret
#endif /* !HAVE_LPMX */ #endif
ENDF __tablejump__ ENDF __tablejump2__
#endif /* defined (L_tablejump) */ #endif /* L_tablejump2 */
#ifdef L_copy_data #ifdef L_copy_data
.section .init4,"ax",@progbits .section .init4,"ax",@progbits
...@@ -2336,116 +2360,65 @@ ENDF __do_clear_bss ...@@ -2336,116 +2360,65 @@ ENDF __do_clear_bss
#ifdef L_ctors #ifdef L_ctors
.section .init6,"ax",@progbits .section .init6,"ax",@progbits
DEFUN __do_global_ctors DEFUN __do_global_ctors
#if defined(__AVR_HAVE_ELPM__) ldi r17, pm_hi8(__ctors_start)
ldi r17, hi8(__ctors_start) ldi r28, pm_lo8(__ctors_end)
ldi r28, lo8(__ctors_end) ldi r29, pm_hi8(__ctors_end)
ldi r29, hi8(__ctors_end) #ifdef __AVR_HAVE_EIJMP_EICALL__
ldi r16, hh8(__ctors_end) ldi r16, pm_hh8(__ctors_end)
#endif /* HAVE_EIJMP */
rjmp .L__do_global_ctors_start rjmp .L__do_global_ctors_start
.L__do_global_ctors_loop: .L__do_global_ctors_loop:
sbiw r28, 2 sbiw r28, 1
#ifdef __AVR_HAVE_EIJMP_EICALL__
sbc r16, __zero_reg__ sbc r16, __zero_reg__
mov r24, r16
#endif /* HAVE_EIJMP */
mov_h r31, r29 mov_h r31, r29
mov_l r30, r28 mov_l r30, r28
out __RAMPZ__, r16 XCALL __tablejump2__
XCALL __tablejump_elpm__
.L__do_global_ctors_start: .L__do_global_ctors_start:
cpi r28, lo8(__ctors_start) cpi r28, pm_lo8(__ctors_start)
cpc r29, r17 cpc r29, r17
ldi r24, hh8(__ctors_start) #ifdef __AVR_HAVE_EIJMP_EICALL__
ldi r24, pm_hh8(__ctors_start)
cpc r16, r24 cpc r16, r24
#endif /* HAVE_EIJMP */
brne .L__do_global_ctors_loop 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__) */
ENDF __do_global_ctors ENDF __do_global_ctors
#endif /* L_ctors */ #endif /* L_ctors */
#ifdef L_dtors #ifdef L_dtors
.section .fini6,"ax",@progbits .section .fini6,"ax",@progbits
DEFUN __do_global_dtors DEFUN __do_global_dtors
#if defined(__AVR_HAVE_ELPM__) ldi r17, pm_hi8(__dtors_start)
ldi r17, hi8(__dtors_end) ldi r28, pm_lo8(__dtors_end)
ldi r28, lo8(__dtors_start) ldi r29, pm_hi8(__dtors_end)
ldi r29, hi8(__dtors_start) #ifdef __AVR_HAVE_EIJMP_EICALL__
ldi r16, hh8(__dtors_start) ldi r16, pm_hh8(__dtors_end)
#endif /* HAVE_EIJMP */
rjmp .L__do_global_dtors_start rjmp .L__do_global_dtors_start
.L__do_global_dtors_loop: .L__do_global_dtors_loop:
sbiw r28, 2 sbiw r28, 1
#ifdef __AVR_HAVE_EIJMP_EICALL__
sbc r16, __zero_reg__ sbc r16, __zero_reg__
mov r24, r16
#endif /* HAVE_EIJMP */
mov_h r31, r29 mov_h r31, r29
mov_l r30, r28 mov_l r30, r28
out __RAMPZ__, r16 XCALL __tablejump2__
XCALL __tablejump_elpm__
.L__do_global_dtors_start: .L__do_global_dtors_start:
cpi r28, lo8(__dtors_end) cpi r28, pm_lo8(__dtors_start)
cpc r29, r17 cpc r29, r17
ldi r24, hh8(__dtors_end) #ifdef __AVR_HAVE_EIJMP_EICALL__
ldi r24, pm_hh8(__dtors_start)
cpc r16, r24 cpc r16, r24
#endif /* HAVE_EIJMP */
brne .L__do_global_dtors_loop 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__) */
ENDF __do_global_dtors ENDF __do_global_dtors
#endif /* L_dtors */ #endif /* L_dtors */
.section .text.libgcc, "ax", @progbits .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 ;; Loading n bytes from Flash; n = 3,4
;; R22... = Flash[Z] ;; R22... = Flash[Z]
......
...@@ -26,8 +26,7 @@ LIB1ASMFUNCS = \ ...@@ -26,8 +26,7 @@ LIB1ASMFUNCS = \
_epilogue \ _epilogue \
_exit \ _exit \
_cleanup \ _cleanup \
_tablejump \ _tablejump2 \
_tablejump_elpm \
_load_3 _load_4 \ _load_3 _load_4 \
_xload_1 _xload_2 _xload_3 _xload_4 \ _xload_1 _xload_2 _xload_3 _xload_4 \
_movmemx \ _movmemx \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment