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
This commit is contained in:
parent
c883e5fb6a
commit
ea3f2b240f
@ -1,3 +1,10 @@
|
||||
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>
|
||||
Maxim Kuznetsov <maxim.kuznetsov@intel.com>
|
||||
Anna Tikhonova <anna.tikhonova@intel.com>
|
||||
|
@ -4932,8 +4932,9 @@
|
||||
(unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
|
||||
UNSPEC_INDEX_JMP))
|
||||
(use (label_ref (match_operand 1 "" "")))
|
||||
(clobber (match_dup 0))]
|
||||
""
|
||||
(clobber (match_dup 0))
|
||||
(clobber (const_int 0))]
|
||||
"!AVR_HAVE_EIJMP_EICALL"
|
||||
"@
|
||||
ijmp
|
||||
push %A0\;push %B0\;ret
|
||||
@ -4942,6 +4943,19 @@
|
||||
(set_attr "isa" "rjmp,rjmp,jmp")
|
||||
(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"
|
||||
[(parallel [(set (match_dup 6)
|
||||
@ -4959,15 +4973,31 @@
|
||||
(label_ref (match_operand 4 "" ""))
|
||||
(pc)))
|
||||
|
||||
(set (match_dup 6)
|
||||
(plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
|
||||
(set (match_dup 10)
|
||||
(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)))
|
||||
(clobber (match_dup 6))])]
|
||||
(clobber (match_dup 10))
|
||||
(clobber (match_dup 8))])]
|
||||
""
|
||||
{
|
||||
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];
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
@ -1,3 +1,14 @@
|
||||
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>
|
||||
Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
||||
|
||||
|
@ -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
|
||||
;; 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
|
||||
|
||||
;; 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
|
||||
ijmp
|
||||
lpm
|
||||
push r0
|
||||
adiw r30, 1
|
||||
lpm
|
||||
push r0
|
||||
ret
|
||||
#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__
|
||||
#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]
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user