This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: __sync_swap* with acq/rel/full memory barrier semantics
On 06/17/2011 02:12 PM, Andrew MacLeod wrote:
> --- machmode.h (working copy)
> *************** extern enum machine_mode ptr_mode;
> *** 275,278 ****
> --- 275,291 ----
> /* Target-dependent machine mode initialization - in insn-modes.c. */
> extern void init_adjust_machine_modes (void);
>
> + /* Memory model types for the __sync_mem* builtins.
> + This must match the order in libstdc++-v3/include/bits/atomic_base.h. */
> + enum memmodel
> + {
> + MEMMODEL_RELAXED = 0,
> + MEMMODEL_CONSUME = 1,
> + MEMMODEL_ACQUIRE = 2,
> + MEMMODEL_RELEASE = 3,
> + MEMMODEL_ACQ_REL = 4,
> + MEMMODEL_SEQ_CST = 5,
> + MEMMODEL_LAST = 6
> + };
This isn't a very machine mode sort of define.
I think coretypes.h is a better choice.
> + static rtx
> + expand_builtin_mem_exchange (enum machine_mode mode, tree exp, rtx target)
Some names include "sync" and some don't?
> + DEF_SYNC_BUILTIN (BUILT_IN_MEM_EXCHANGE_N,
> + "__sync_mem_exchange",
> + BT_FN_VOID_VAR, ATTR_NOTHROW_LEAF_LIST)
Similarly...
> + (define_expand "sync_mem_exchange<mode>"
> + [(set (match_operand:SWI 0 "register_operand" "=<r>")
> + (unspec_volatile:SWI
> + [(match_operand:SWI 1 "memory_operand" "+m")] UNSPECV_MEM_XCHG))
> + (set (match_dup 1)
> + (match_operand:SWI 2 "register_operand" "0"))
> + (match_operand:SI 3 "const_int_operand" "n")]
> + ""
> + {
> + /* lock_test_and_set is only an acquire barrier. If a stronger barrier is
> + required, issue a release barrier before the insn. */
> + if (INTVAL (operands[3]) == MEMMODEL_ACQ_REL ||
> + INTVAL (operands[3]) == MEMMODEL_SEQ_CST)
> + emit_insn (gen_memory_barrier ());
> + emit_insn (gen_sync_lock_test_and_set<mode> (operands[0],
> + operands[1],
> + operands[2]));
> + DONE;
The xchg instruction is a full barrier; no need for anything extra here.
Indeed, you needn't define UNSPECV_MEM_XCHG either. This could be as
simple as
(define_expand "sync_mem_exchange<mode>"
[(match_operand:SWI 0 "register_operand" "") ;; output
(match_operand:SWI 1 "memory_operand" "") ;; memory
(match_operand:SWI 2 "register_operand" "") ;; input
(match_operand:SI 3 "const_int_operand" "")] ;; memory model
""
{
/* On i386 the xchg instruction is a full barrier. Thus we
can completely ignore the memory model operand. */
emit_insn (gen_sync_lock_test_and_set<mode>
(operands[0], operands[1], operands[2]));
DONE;
})
r~