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
This commit is contained in:
parent
d8dd52a990
commit
d93417c86a
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"))]
|
||||
(clobber (match_scratch:QI 4 "=&d"))
|
||||
(clobber (match_scratch:QI 5 "=&d"))]
|
||||
""
|
||||
"ldi %1,lo8(%0)
|
||||
ldi %2,hi8(%0)
|
||||
ldi %3,hlo8(%0)
|
||||
ldi %4,hhi8(%0)
|
||||
1: subi %1,1
|
||||
sbci %2,0
|
||||
"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")
|
||||
|
|
Loading…
Reference in New Issue