[AArch64] Add atomic load-operate instructions.
authorMatthew Wahab <matthew.wahab@arm.com>
Tue, 22 Sep 2015 09:30:51 +0000 (09:30 +0000)
committerMatthew Wahab <mwahab@gcc.gnu.org>
Tue, 22 Sep 2015 09:30:51 +0000 (09:30 +0000)
2015-09-22  Matthew Wahab  <matthew.wahab@arm.com>

* config/aarch64/aarch64/atomics.md (UNSPECV_ATOMIC_LDOP): New.
(UNSPECV_ATOMIC_LDOP_OR): New.
(UNSPECV_ATOMIC_LDOP_BIC): New.
(UNSPECV_ATOMIC_LDOP_XOR): New.
(UNSPECV_ATOMIC_LDOP_PLUS): New.
(ATOMIC_LDOP): New.
(atomic_ldop): New.
(aarch64_atomic_load<atomic_ldop><mode>): New.

From-SVN: r228000

gcc/ChangeLog
gcc/config/aarch64/atomics.md

index 568d1d758c642c6d5fe02d9cf67b2446ca0d3b11..27e773b5e989d4727d2c01c913e84e85359ebca1 100644 (file)
@@ -1,3 +1,14 @@
+2015-09-22  Matthew Wahab  <matthew.wahab@arm.com>
+
+       * config/aarch64/aarch64/atomics.md (UNSPECV_ATOMIC_LDOP): New.
+       (UNSPECV_ATOMIC_LDOP_OR): New.
+       (UNSPECV_ATOMIC_LDOP_BIC): New.
+       (UNSPECV_ATOMIC_LDOP_XOR): New.
+       (UNSPECV_ATOMIC_LDOP_PLUS): New.
+       (ATOMIC_LDOP): New.
+       (atomic_ldop): New.
+       (aarch64_atomic_load<atomic_ldop><mode>): New.
+
 2015-09-22  Matthew Wahab  <matthew.wahab@arm.com>
 
        * config/aarch64/aarch64.md
index cb8053942c83709b6bc11269ac2447807076f2fb..11a9d1374c8c0d4308cdbc58122daf5bb6895832 100644 (file)
     UNSPECV_ATOMIC_CAS                 ; Represent an atomic CAS.
     UNSPECV_ATOMIC_SWP                 ; Represent an atomic SWP.
     UNSPECV_ATOMIC_OP                  ; Represent an atomic operation.
+    UNSPECV_ATOMIC_LDOP                        ; Represent an atomic load-operation
+    UNSPECV_ATOMIC_LDOP_OR             ; Represent an atomic load-or
+    UNSPECV_ATOMIC_LDOP_BIC            ; Represent an atomic load-bic
+    UNSPECV_ATOMIC_LDOP_XOR            ; Represent an atomic load-xor
+    UNSPECV_ATOMIC_LDOP_PLUS           ; Represent an atomic load-add
 ])
 
+;; Iterators for load-operate instructions.
+
+(define_int_iterator ATOMIC_LDOP
+ [UNSPECV_ATOMIC_LDOP_OR UNSPECV_ATOMIC_LDOP_BIC
+  UNSPECV_ATOMIC_LDOP_XOR UNSPECV_ATOMIC_LDOP_PLUS])
+
+(define_int_attr atomic_ldop
+ [(UNSPECV_ATOMIC_LDOP_OR "set") (UNSPECV_ATOMIC_LDOP_BIC "clr")
+  (UNSPECV_ATOMIC_LDOP_XOR "eor") (UNSPECV_ATOMIC_LDOP_PLUS "add")])
+
+;; Instruction patterns.
+
 (define_expand "atomic_compare_and_swap<mode>"
   [(match_operand:SI 0 "register_operand" "")                  ;; bool out
    (match_operand:ALLI 1 "register_operand" "")                        ;; val out
     else
       return "casal<atomic_sfx>\t%<w>0, %<w>2, %1";
 })
+
+;; Atomic load-op: Load data, operate, store result, keep data.
+
+(define_insn "aarch64_atomic_load<atomic_ldop><mode>"
+ [(set (match_operand:ALLI 0 "register_operand" "=r")
+   (match_operand:ALLI 1 "aarch64_sync_memory_operand" "+Q"))
+  (set (match_dup 1)
+   (unspec_volatile:ALLI
+    [(match_dup 1)
+     (match_operand:ALLI 2 "register_operand")
+     (match_operand:SI 3 "const_int_operand")]
+    ATOMIC_LDOP))]
+ "TARGET_LSE && reload_completed"
+ {
+   enum memmodel model = memmodel_from_int (INTVAL (operands[3]));
+   if (is_mm_relaxed (model))
+     return "ld<atomic_ldop><atomic_sfx>\t%<w>2, %<w>0, %1";
+   else if (is_mm_acquire (model) || is_mm_consume (model))
+     return "ld<atomic_ldop>a<atomic_sfx>\t%<w>2, %<w>0, %1";
+   else if (is_mm_release (model))
+     return "ld<atomic_ldop>l<atomic_sfx>\t%<w>2, %<w>0, %1";
+   else
+     return "ld<atomic_ldop>al<atomic_sfx>\t%<w>2, %<w>0, %1";
+ })