This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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~


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]