sync.md (atomic_exchange<mode>): New expander.
authorOleg Endo <olegendo@gcc.gnu.org>
Fri, 2 Mar 2012 21:07:21 +0000 (21:07 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Fri, 2 Mar 2012 21:07:21 +0000 (21:07 +0000)
* config/sh/sync.md (atomic_exchange<mode>): New expander.
(atomic_exchange<mode>_soft): New insn.

From-SVN: r184827

gcc/ChangeLog
gcc/config/sh/sync.md

index 009097e751353688ab70906a8a14e6166867b81d..c0242a9e62b4b603c1b801a5e113d2ed45025b7f 100644 (file)
@@ -1,9 +1,14 @@
 2012-03-02  Oleg Endo  <olegendo@gcc.gnu.org>
 
-        * config/sh/sync.md: Update copyright notice dates.
+       * config/sh/sync.md (atomic_exchange<mode>): New expander.
+       (atomic_exchange<mode>_soft): New insn.
+
+2012-03-02  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       * config/sh/sync.md: Update copyright notice dates.
        (atomic_compare_and_swap<mode>): Use SImode for return value instead
        of QImode.
-        (atomic_compare_and_swap<mode>_soft): Likewise.
+       (atomic_compare_and_swap<mode>_soft): Likewise.
 
 2012-03-02  Oleg Endo  <olegendo@gcc.gnu.org>
  
index 88e0ce22089e9dcd9ee837a2a20765745288df0d..5e55947b66b8040d1aa743cca6c647b8382b2ab9 100644 (file)
 }
   [(set_attr "length" "20")])
 
+(define_expand "atomic_exchange<mode>"
+  [(match_operand:I124 0 "register_operand" "")                ;; oldval output
+   (match_operand:I124 1 "memory_operand" "")          ;; memory
+   (match_operand:I124 2 "register_operand" "")                ;; newval input
+   (match_operand:SI 3 "const_int_operand" "")]                ;; memory model
+  "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+{
+  rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
+  emit_insn (gen_atomic_exchange<mode>_soft
+            (operands[0], addr, operands[2]));
+  if (<MODE>mode == QImode)
+    emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
+                                    operands[0]));
+  else if (<MODE>mode == HImode)
+    emit_insn (gen_zero_extendhisi2 (gen_lowpart (SImode, operands[0]),
+                                    operands[0]));
+  DONE;
+})
+
+(define_insn "atomic_exchange<mode>_soft"
+  [(set (match_operand:I124 0 "register_operand" "=&u")
+       (mem:I124 (match_operand:SI 1 "register_operand" "u")))
+   (set (mem:I124 (match_dup 1))
+       (unspec:I124
+         [(match_operand:I124 2 "register_operand" "u")] UNSPEC_ATOMIC))
+   (clobber (reg:SI R0_REG))
+   (clobber (reg:SI R1_REG))]
+  "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+{
+  return "mova 1f,r0"                          "\n"
+        "      .align 2"                       "\n"
+        "      mov     r15,r1"                 "\n"
+        "      mov     #(0f-1f),r15"           "\n"
+        "0:    mov.<i124suffix>        @%1,%0" "\n"
+        "      mov.<i124suffix>        %2,@%1" "\n"
+        "1:    mov     r1,r15";
+}
+  [(set_attr "length" "14")])
+
 (define_expand "atomic_fetch_<fetchop_name><mode>"
   [(set (match_operand:I124 0 "register_operand" "")
        (match_operand:I124 1 "memory_operand" ""))