PR target/52496
authorgjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Mar 2012 11:14:05 +0000 (11:14 +0000)
committergjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Mar 2012 11:14:05 +0000 (11:14 +0000)
* 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
gcc/config/avr/avr.c
gcc/config/avr/avr.md

index 397ad10..7594d2d 100644 (file)
@@ -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>
 
index 0fcec0d..e52c5d8 100644 (file)
@@ -9973,6 +9973,14 @@ avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
 \f
 /* 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;
       }
   
index 410cabb..33a871e 100644 (file)
@@ -69,6 +69,7 @@
    UNSPEC_COPYSIGN
    UNSPEC_IDENTITY
    UNSPEC_INSERT_BITS
+   UNSPEC_MEMORY_BARRIER
    ])
 
 (define_c_enum "unspecv"
    (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")])
 
   [(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")])
   [(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")])
   [(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")])
   [(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")])
 ;; 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
    (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")