Commit d93417c8 by Georg-Johann Lay Committed by Georg-Johann Lay

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
parent d8dd52a9
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> 2012-03-07 Oleg Endo <olegendo@gcc.gnu.org>
Kaz Kojima <kkojima@gcc.gnu.org> Kaz Kojima <kkojima@gcc.gnu.org>
......
...@@ -9973,6 +9973,14 @@ avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen) ...@@ -9973,6 +9973,14 @@ avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
/* Helper for __builtin_avr_delay_cycles */ /* 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 static void
avr_expand_delay_cycles (rtx operands0) avr_expand_delay_cycles (rtx operands0)
{ {
...@@ -9984,7 +9992,8 @@ avr_expand_delay_cycles (rtx operands0) ...@@ -9984,7 +9992,8 @@ avr_expand_delay_cycles (rtx operands0)
{ {
loop_count = ((cycles - 9) / 6) + 1; loop_count = ((cycles - 9) / 6) + 1;
cycles_used = ((loop_count - 1) * 6) + 9; 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; cycles -= cycles_used;
} }
...@@ -9994,7 +10003,8 @@ avr_expand_delay_cycles (rtx operands0) ...@@ -9994,7 +10003,8 @@ avr_expand_delay_cycles (rtx operands0)
if (loop_count > 0xFFFFFF) if (loop_count > 0xFFFFFF)
loop_count = 0xFFFFFF; loop_count = 0xFFFFFF;
cycles_used = ((loop_count - 1) * 5) + 7; 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; cycles -= cycles_used;
} }
...@@ -10004,7 +10014,8 @@ avr_expand_delay_cycles (rtx operands0) ...@@ -10004,7 +10014,8 @@ avr_expand_delay_cycles (rtx operands0)
if (loop_count > 0xFFFF) if (loop_count > 0xFFFF)
loop_count = 0xFFFF; loop_count = 0xFFFF;
cycles_used = ((loop_count - 1) * 4) + 5; 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; cycles -= cycles_used;
} }
...@@ -10014,7 +10025,8 @@ avr_expand_delay_cycles (rtx operands0) ...@@ -10014,7 +10025,8 @@ avr_expand_delay_cycles (rtx operands0)
if (loop_count > 255) if (loop_count > 255)
loop_count = 255; loop_count = 255;
cycles_used = loop_count * 3; 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; cycles -= cycles_used;
} }
......
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
UNSPEC_COPYSIGN UNSPEC_COPYSIGN
UNSPEC_IDENTITY UNSPEC_IDENTITY
UNSPEC_INSERT_BITS UNSPEC_INSERT_BITS
UNSPEC_MEMORY_BARRIER
]) ])
(define_c_enum "unspecv" (define_c_enum "unspecv"
...@@ -5237,18 +5238,36 @@ ...@@ -5237,18 +5238,36 @@
(set_attr "length" "1")]) (set_attr "length" "1")])
;; Enable Interrupts ;; Enable Interrupts
(define_insn "enable_interrupt" (define_expand "enable_interrupt"
[(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)] [(clobber (const_int 0))]
"" ""
"sei" {
[(set_attr "length" "1") rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
(set_attr "cc" "none")]) MEM_VOLATILE_P (mem) = 1;
emit_insn (gen_cli_sei (const1_rtx, mem));
DONE;
})
;; Disable Interrupts ;; Disable Interrupts
(define_insn "disable_interrupt" (define_expand "disable_interrupt"
[(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)] [(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 "length" "1")
(set_attr "cc" "none")]) (set_attr "cc" "none")])
...@@ -5355,10 +5374,12 @@ ...@@ -5355,10 +5374,12 @@
[(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n") [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
(const_int 1)] (const_int 1)]
UNSPECV_DELAY_CYCLES) 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) "ldi %2,lo8(%0)
1: dec %1 1: dec %2
brne 1b" brne 1b"
[(set_attr "length" "3") [(set_attr "length" "3")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
...@@ -5367,11 +5388,13 @@ ...@@ -5367,11 +5388,13 @@
[(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n") [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
(const_int 2)] (const_int 2)]
UNSPECV_DELAY_CYCLES) 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 %A2,lo8(%0)
ldi %B1,hi8(%0) ldi %B2,hi8(%0)
1: sbiw %A1,1 1: sbiw %A2,1
brne 1b" brne 1b"
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
...@@ -5380,16 +5403,18 @@ ...@@ -5380,16 +5403,18 @@
[(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
(const_int 3)] (const_int 3)]
UNSPECV_DELAY_CYCLES) 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 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,lo8(%0)
ldi %2,hi8(%0) ldi %3,hi8(%0)
ldi %3,hlo8(%0) ldi %4,hlo8(%0)
1: subi %1,1 1: subi %2,1
sbci %2,0
sbci %3,0 sbci %3,0
sbci %4,0
brne 1b" brne 1b"
[(set_attr "length" "7") [(set_attr "length" "7")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
...@@ -5398,19 +5423,21 @@ ...@@ -5398,19 +5423,21 @@
[(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
(const_int 4)] (const_int 4)]
UNSPECV_DELAY_CYCLES) 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 2 "=&d"))
(clobber (match_scratch:QI 3 "=&d")) (clobber (match_scratch:QI 3 "=&d"))
(clobber (match_scratch:QI 4 "=&d"))] (clobber (match_scratch:QI 4 "=&d"))
"" (clobber (match_scratch:QI 5 "=&d"))]
"ldi %1,lo8(%0) ""
ldi %2,hi8(%0) "ldi %2,lo8(%0)
ldi %3,hlo8(%0) ldi %3,hi8(%0)
ldi %4,hhi8(%0) ldi %4,hlo8(%0)
1: subi %1,1 ldi %5,hhi8(%0)
sbci %2,0 1: subi %2,1
sbci %3,0 sbci %3,0
sbci %4,0 sbci %4,0
sbci %5,0
brne 1b" brne 1b"
[(set_attr "length" "9") [(set_attr "length" "9")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
...@@ -5796,9 +5823,22 @@ ...@@ -5796,9 +5823,22 @@
;; CPU instructions ;; CPU instructions
;; NOP taking 1 or 2 Ticks ;; 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")] [(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 nop
...@@ -5807,16 +5847,40 @@ ...@@ -5807,16 +5847,40 @@
(set_attr "cc" "none")]) (set_attr "cc" "none")])
;; SLEEP ;; SLEEP
(define_insn "sleep" (define_expand "sleep"
[(unspec_volatile [(const_int 0)] UNSPECV_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" "sleep"
[(set_attr "length" "1") [(set_attr "length" "1")
(set_attr "cc" "none")]) (set_attr "cc" "none")])
;; WDR ;; WDR
(define_insn "wdr" (define_expand "wdr"
[(unspec_volatile [(const_int 0)] UNSPECV_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" "wdr"
[(set_attr "length" "1") [(set_attr "length" "1")
......
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