From 5af5ea69b041df957178990db6a66966accc53a9 Mon Sep 17 00:00:00 2001 From: gjl Date: Thu, 8 Mar 2012 11:14:05 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 19 +++++++ gcc/config/avr/avr.c | 20 ++++++-- gcc/config/avr/avr.md | 138 ++++++++++++++++++++++++++++++++++++-------------- 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 + + 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 Kaz Kojima 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") -- 2.11.4.GIT