This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch,AVR]: Fix PR52496: Add memory barriers to built-ins


This patch adds memory barriers to

__builtin_avr_nop
__builtin_avr_sei
__builtin_avr_cli
__builtin_avr_wdr
__builtin_avr_sleep
__builtin_avr_delay_cycles

so that their code cannot be dragged over memory accesses.

Ok for trunk?

	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.
	(*sleep): New insn from former "sleep" with memory clobber.
Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md	(revision 185031)
+++ config/avr/avr.md	(working copy)
@@ -69,6 +69,7 @@ (define_c_enum "unspec"
    UNSPEC_COPYSIGN
    UNSPEC_IDENTITY
    UNSPEC_INSERT_BITS
+   UNSPEC_MEMORY_BARRIER
    ])
 
 (define_c_enum "unspecv"
@@ -5236,18 +5237,36 @@ (define_insn "popqi"
    (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")])
 
@@ -5354,10 +5373,12 @@ (define_insn "delay_cycles_1"
   [(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")])
@@ -5366,11 +5387,13 @@ (define_insn "delay_cycles_2"
   [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
                      (const_int 2)]
                     UNSPECV_DELAY_CYCLES)
-   (clobber (match_scratch:HI 1 "=&w"))]
-  ""
-  "ldi %A1,lo8(%0)
-	ldi %B1,hi8(%0)
-	1: sbiw %A1,1
+   (set (match_operand:BLK 1 "" "")
+	(unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))
+   (clobber (match_scratch:HI 2 "=&w"))]
+  ""
+  "ldi %A2,lo8(%0)
+	ldi %B2,hi8(%0)
+	1: sbiw %A2,1
 	brne 1b"
   [(set_attr "length" "4")
    (set_attr "cc" "clobber")])
@@ -5379,16 +5402,18 @@ (define_insn "delay_cycles_3"
   [(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")])
@@ -5397,19 +5422,21 @@ (define_insn "delay_cycles_4"
   [(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")])
@@ -5795,9 +5822,22 @@ (define_insn "*bswapsi2.libgcc"
 ;; 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
@@ -5806,16 +5846,40 @@ (define_insn "nopv"
    (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")
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 185032)
+++ config/avr/avr.c	(working copy)
@@ -9973,6 +9973,14 @@ avr_out_movmem (rtx insn ATTRIBUTE_UNUSE
 
 /* 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]