aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr/avr.md
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2014-09-11 08:08:17 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2014-09-11 08:08:17 +0000
commitea3f2b240febca348d795e19ba908a34f78b206d (patch)
tree462a929a1a108e79a3e7461e386a0bfb888077a2 /gcc/config/avr/avr.md
parentc883e5fb6a12718325cebeb653a4ccf4668a723c (diff)
downloadgcc-ea3f2b240febca348d795e19ba908a34f78b206d.zip
gcc-ea3f2b240febca348d795e19ba908a34f78b206d.tar.gz
gcc-ea3f2b240febca348d795e19ba908a34f78b206d.tar.bz2
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
Diffstat (limited to 'gcc/config/avr/avr.md')
-rw-r--r--gcc/config/avr/avr.md42
1 files changed, 36 insertions, 6 deletions
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index a959b9b..ecedbbd 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -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];
+ }
})