Patchwork [i386] : Implement atomic_fetch_sub

login
register
mail settings
Submitter Uros Bizjak
Date Aug. 3, 2012, 6:40 a.m.
Message ID <CAFULd4ZG8hH20HR0Dix5i7C0hVz7Bm4jvmMPH9UjZYn_5gzSxw@mail.gmail.com>
Download mbox | patch
Permalink /patch/174895/
State New
Headers show

Comments

Uros Bizjak - Aug. 3, 2012, 6:40 a.m.
Hello!

We can implement atomic_fetch_sub with atomic_fetch_add and inverted
operand 2. However, we have to prevent overflows with negation, so
only const_int operand 2 is allowed in the expander.

2012-08-02  Uros Bizjak  <ubizjak@gmail.com>

        PR target/54087
        * config/i386/sync.md (atomic_fetch_sub<mode>): New expander.

Tested on x86_64-pc-linux-gnu {,-m32}.

I will wait for a day for possible comments.

Uros.

Patch

Index: config/i386/sync.md
===================================================================
--- config/i386/sync.md	(revision 190111)
+++ config/i386/sync.md	(working copy)
@@ -520,6 +520,31 @@ 
   return "lock{%;} add{<imodesuffix>}\t{%1, %0|%0, %1}";
 })
 
+;; We can use atomic_fetch_add with negated operand 2 to implement
+;; atomic_fetch_sub.  We have to prevent overflows with negation, so
+;; only const_int operand 2 is allowed.
+(define_expand "atomic_fetch_sub<mode>"
+  [(set (match_operand:SWI 0 "register_operand")
+	(unspec_volatile:SWI
+	  [(match_operand:SWI 1 "memory_operand")
+	   (match_operand:SI 3 "const_int_operand")]		;; model
+	  UNSPECV_XCHG))
+   (set (match_dup 1)
+	(minus:SWI (match_dup 1)
+		   (match_operand:SWI 2 "const_int_operand")))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_XADD"
+{
+  /* Avoid overflows.  */
+  if (mode_signbit_p (<MODE>mode, operands[2]))
+    FAIL;
+
+  emit_insn (gen_atomic_fetch_add<mode> (operands[0], operands[1],
+					 negate_rtx (<MODE>mode, operands[2]),
+					 operands[3]));
+  DONE;
+})
+
 ;; Recall that xchg implicitly sets LOCK#, so adding it again wastes space.
 ;; In addition, it is always a full barrier, so we can ignore the memory model.
 (define_insn "atomic_exchange<mode>"