summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-08 11:14:05 +0000
committergjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-08 11:14:05 +0000
commit5af5ea69b041df957178990db6a66966accc53a9 (patch)
tree07960c4f7d30e858b4b8ea747176e674755b2a8e
parent569455ec2b2ecb11150b2dce2f8cf1a2fffc20df (diff)
downloadgcc-5af5ea69b041df957178990db6a66966accc53a9.tar.gz
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". git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185100 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/config/avr/avr.c20
-rw-r--r--gcc/config/avr/avr.md138
3 files changed, 136 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 397ad1042b6..7594d2dd74c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+2012-03-08 Georg-Johann Lay <avr@gjlay.de>
+
+ 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".
+
2012-03-07 Oleg Endo <olegendo@gcc.gnu.org>
Kaz Kojima <kkojima@gcc.gnu.org>
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 0fcec0dff1a..e52c5d85f6b 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;
}
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 410cabb2b95..33a871e04d9 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -69,6 +69,7 @@
UNSPEC_COPYSIGN
UNSPEC_IDENTITY
UNSPEC_INSERT_BITS
+ UNSPEC_MEMORY_BARRIER
])
(define_c_enum "unspecv"
@@ -5237,18 +5238,36 @@
(set_attr "length" "1")])
;; Enable Interrupts
-(define_insn "enable_interrupt"
- [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
+(define_expand "enable_interrupt"
+ [(clobber (const_int 0))]
""
- "sei"
- [(set_attr "length" "1")
- (set_attr "cc" "none")])
+ {
+ rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (mem) = 1;
+ emit_insn (gen_cli_sei (const1_rtx, mem));
+ DONE;
+ })
;; Disable Interrupts
-(define_insn "disable_interrupt"
- [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
+(define_expand "disable_interrupt"
+ [(clobber (const_int 0))]
""
- "cli"
+ {
+ rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (mem) = 1;
+ emit_insn (gen_cli_sei (const0_rtx, mem));
+ DONE;
+ })
+
+(define_insn "cli_sei"
+ [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
+ UNSPECV_ENABLE_IRQS)
+ (set (match_operand:BLK 1 "" "")
+ (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))]
+ ""
+ "@
+ cli
+ sei"
[(set_attr "length" "1")
(set_attr "cc" "none")])
@@ -5355,10 +5374,12 @@
[(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
(const_int 1)]
UNSPECV_DELAY_CYCLES)
- (clobber (match_scratch:QI 1 "=&d"))]
+ (set (match_operand:BLK 1 "" "")
+ (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))
+ (clobber (match_scratch:QI 2 "=&d"))]
""
- "ldi %1,lo8(%0)
- 1: dec %1
+ "ldi %2,lo8(%0)
+ 1: dec %2
brne 1b"
[(set_attr "length" "3")
(set_attr "cc" "clobber")])
@@ -5367,11 +5388,13 @@
[(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
(const_int 2)]
UNSPECV_DELAY_CYCLES)
- (clobber (match_scratch:HI 1 "=&w"))]
+ (set (match_operand:BLK 1 "" "")
+ (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))
+ (clobber (match_scratch:HI 2 "=&w"))]
""
- "ldi %A1,lo8(%0)
- ldi %B1,hi8(%0)
- 1: sbiw %A1,1
+ "ldi %A2,lo8(%0)
+ ldi %B2,hi8(%0)
+ 1: sbiw %A2,1
brne 1b"
[(set_attr "length" "4")
(set_attr "cc" "clobber")])
@@ -5380,16 +5403,18 @@
[(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
(const_int 3)]
UNSPECV_DELAY_CYCLES)
- (clobber (match_scratch:QI 1 "=&d"))
+ (set (match_operand:BLK 1 "" "")
+ (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))
(clobber (match_scratch:QI 2 "=&d"))
- (clobber (match_scratch:QI 3 "=&d"))]
+ (clobber (match_scratch:QI 3 "=&d"))
+ (clobber (match_scratch:QI 4 "=&d"))]
""
- "ldi %1,lo8(%0)
- ldi %2,hi8(%0)
- ldi %3,hlo8(%0)
- 1: subi %1,1
- sbci %2,0
+ "ldi %2,lo8(%0)
+ ldi %3,hi8(%0)
+ ldi %4,hlo8(%0)
+ 1: subi %2,1
sbci %3,0
+ sbci %4,0
brne 1b"
[(set_attr "length" "7")
(set_attr "cc" "clobber")])
@@ -5398,19 +5423,21 @@
[(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
(const_int 4)]
UNSPECV_DELAY_CYCLES)
- (clobber (match_scratch:QI 1 "=&d"))
+ (set (match_operand:BLK 1 "" "")
+ (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))
(clobber (match_scratch:QI 2 "=&d"))
(clobber (match_scratch:QI 3 "=&d"))
- (clobber (match_scratch:QI 4 "=&d"))]
- ""
- "ldi %1,lo8(%0)
- ldi %2,hi8(%0)
- ldi %3,hlo8(%0)
- ldi %4,hhi8(%0)
- 1: subi %1,1
- sbci %2,0
+ (clobber (match_scratch:QI 4 "=&d"))
+ (clobber (match_scratch:QI 5 "=&d"))]
+ ""
+ "ldi %2,lo8(%0)
+ ldi %3,hi8(%0)
+ ldi %4,hlo8(%0)
+ ldi %5,hhi8(%0)
+ 1: subi %2,1
sbci %3,0
sbci %4,0
+ sbci %5,0
brne 1b"
[(set_attr "length" "9")
(set_attr "cc" "clobber")])
@@ -5796,9 +5823,22 @@
;; CPU instructions
;; NOP taking 1 or 2 Ticks
-(define_insn "nopv"
+(define_expand "nopv"
+ [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
+ UNSPECV_NOP)
+ (set (match_dup 1)
+ (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))])]
+ ""
+ {
+ operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (operands[1]) = 1;
+ })
+
+(define_insn "*nopv"
[(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
- UNSPECV_NOP)]
+ UNSPECV_NOP)
+ (set (match_operand:BLK 1 "" "")
+ (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))]
""
"@
nop
@@ -5807,16 +5847,40 @@
(set_attr "cc" "none")])
;; SLEEP
-(define_insn "sleep"
- [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
+(define_expand "sleep"
+ [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
+ (set (match_dup 0)
+ (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))])]
+ ""
+ {
+ operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (operands[0]) = 1;
+ })
+
+(define_insn "*sleep"
+ [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
+ (set (match_operand:BLK 0 "" "")
+ (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
""
"sleep"
[(set_attr "length" "1")
(set_attr "cc" "none")])
;; WDR
-(define_insn "wdr"
- [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
+(define_expand "wdr"
+ [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
+ (set (match_dup 0)
+ (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))])]
+ ""
+ {
+ operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (operands[0]) = 1;
+ })
+
+(define_insn "*wdr"
+ [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
+ (set (match_operand:BLK 0 "" "")
+ (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
""
"wdr"
[(set_attr "length" "1")