Hello, ARMv8.1 adds atomic swap and atomic load-operate instructions with optional memory ordering specifiers. This patch adds the ARMv8.1 atomic load-operate instructions.
Tested the series for aarch64-none-linux-gnu with native bootstrap and make check. Also tested for aarch64-none-elf with cross-compiled check-gcc on an ARMv8.1 emulator with +lse enabled by default. Ok for trunk? Matthew 2015-09-17 Matthew Wahab <matthew.wa...@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 6a8a83c4efbd607924f0630779d4915c9dad079c Mon Sep 17 00:00:00 2001 From: Matthew Wahab <matthew.wa...@arm.com> Date: Mon, 10 Aug 2015 17:02:08 +0100 Subject: [PATCH 3/5] Add atomic load-operate instructions. Change-Id: I3746875bad7469403bee7df952f0ba565e4abc71 --- gcc/config/aarch64/atomics.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/gcc/config/aarch64/atomics.md b/gcc/config/aarch64/atomics.md index 0e71002..b7b6fb5 100644 --- a/gcc/config/aarch64/atomics.md +++ b/gcc/config/aarch64/atomics.md @@ -29,8 +29,25 @@ 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 @@ -541,3 +558,27 @@ 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"; + }) -- 2.1.4