On Thu, Sep 17, 2015 at 05:42:35PM +0100, Matthew Wahab wrote: > 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")]) There is precedent (atomic_optab, atomic_op_operand, const_atomic, etc.) for these living in config/aarch64/iterators.md so they should be moved there. Presumably the difficulty with that is to do with the position of the "unspecv" define_c_enum? I'd argue that is in the wrong place too... If you want to leave this to a cleanup patch in stage 3 that is fine. This patch is OK for trunk. Thanks, James > + > +;; 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 >