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~