aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr/avr.c
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2012-03-08 11:14:05 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2012-03-08 11:14:05 +0000
commitd93417c86a355886015684eb5c43a45b09423d7a (patch)
tree07960c4f7d30e858b4b8ea747176e674755b2a8e /gcc/config/avr/avr.c
parentd8dd52a990a5aefa3a865333a077873c3e5d14be (diff)
downloadgcc-d93417c86a355886015684eb5c43a45b09423d7a.zip
gcc-d93417c86a355886015684eb5c43a45b09423d7a.tar.gz
gcc-d93417c86a355886015684eb5c43a45b09423d7a.tar.bz2
re PR target/52496 (avr-specific built-ins missing memory barrier)
PR target/52496 * config/avr/avr.c (avr_mem_clobber): New static function. (avr_expand_delay_cycles): Add memory clobber operand to delay_cycles_1, delay_cycles_2, delay_cycles_3, delay_cycles_4. * config/avr/avr.md (unspec): Add UNSPEC_MEMORY_BARRIER. (enable_interrupt, disable_interrupt): New expander. (nopv, sleep, wdr): New expanders. (delay_cycles_1): Add memory clobber. (delay_cycles_2): Add memory clobber. (delay_cycles_3): Add memory clobber. (delay_cycles_4): Add memory clobber. (cli_sei): New insn from former "enable_interrupt", "disable_interrupt" with memory clobber. (*wdt): New insn from former "wdt" with memory clobber. (*nopv): Similar, but for "nopv". (*sleep): Similar, but for "sleep". From-SVN: r185100
Diffstat (limited to 'gcc/config/avr/avr.c')
-rw-r--r--gcc/config/avr/avr.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 0fcec0d..e52c5d8 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -9973,6 +9973,14 @@ avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
/* Helper for __builtin_avr_delay_cycles */
+static rtx
+avr_mem_clobber (void)
+{
+ rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (mem) = 1;
+ return mem;
+}
+
static void
avr_expand_delay_cycles (rtx operands0)
{
@@ -9984,7 +9992,8 @@ avr_expand_delay_cycles (rtx operands0)
{
loop_count = ((cycles - 9) / 6) + 1;
cycles_used = ((loop_count - 1) * 6) + 9;
- emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode)));
+ emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
+ avr_mem_clobber()));
cycles -= cycles_used;
}
@@ -9994,7 +10003,8 @@ avr_expand_delay_cycles (rtx operands0)
if (loop_count > 0xFFFFFF)
loop_count = 0xFFFFFF;
cycles_used = ((loop_count - 1) * 5) + 7;
- emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode)));
+ emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
+ avr_mem_clobber()));
cycles -= cycles_used;
}
@@ -10004,7 +10014,8 @@ avr_expand_delay_cycles (rtx operands0)
if (loop_count > 0xFFFF)
loop_count = 0xFFFF;
cycles_used = ((loop_count - 1) * 4) + 5;
- emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode)));
+ emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
+ avr_mem_clobber()));
cycles -= cycles_used;
}
@@ -10014,7 +10025,8 @@ avr_expand_delay_cycles (rtx operands0)
if (loop_count > 255)
loop_count = 255;
cycles_used = loop_count * 3;
- emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode)));
+ emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
+ avr_mem_clobber()));
cycles -= cycles_used;
}