diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-20 04:54:11 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-20 04:54:11 +0000 |
commit | 87121034113f8b3bb96db325d3260d806f4e103a (patch) | |
tree | 4acdd6c4898d643fa0b840941a2d12315366ec66 /gcc/optabs.c | |
parent | 039f212de27c41c806d96f52be4b534138dbfc10 (diff) | |
download | gcc-87121034113f8b3bb96db325d3260d806f4e103a.tar.gz |
* builtins.c (expand_builtin_sync_operation): Revert last change.
* optabs.c (expand_bool_compare_and_swap): Compare vs old value,
not vs new value.
(expand_compare_and_swap_loop): Likewise.
(expand_sync_operation): Remove fallback from NAND to AND; invert
memory operand when expanding from cmpxchg.
(expand_sync_fetch_operation): Likewise.
* doc/extend.texi (Atomic Builtins): Fix docs for nand and
compare-and-swap.
* config/alpha/alpha.c (alpha_split_atomic_op): Invert memory operand
when implementing NAND. Fix double-add for AFTER.
* config/alpha/sync.md (sync_nand<I48MODE>): Invert memory operand.
(sync_old_nand<I48MODE>, sync_new_nand<I48MODE>): Likewise.
(sync_compare_and_swap<I48MODE>): Fix compare vs zero. Return old
memory value.
(sync_lock_test_and_set<I48MODE>): Remove extra label and last
memory barrier.
* config/i386/sync.md (sync_compare_and_swap<IMODE>): Fix pattern
to return old memory value.
(sync_compare_and_swap_cc<IMODE>): Likewise.
* config/ia64/ia64.c (ia64_dependencies_evaluation_hook): Early
return pre-reload. Don't consider output or anti dependencies.
* config/ia64/sync.md (IMODE): New.
(modesuffix): Add QI and HI.
(memory_barrier): Simplify expansion.
(sync_compare_and_swap<IMODE>): Use IMODE, not I48MODE.
(cmpxchg_acq_<IMODE>): Likewise.
(sync_lock_test_and_set<IMODE>): Likewise.
(sync_lock_release<IMODE>): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98436 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 61 |
1 files changed, 25 insertions, 36 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 90a42c25d64..e1b9e3d3b76 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -5588,12 +5588,17 @@ expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target) if (icode == CODE_FOR_nothing) return NULL_RTX; + /* Ensure that if old_val == mem, that we're not comparing + against an old value. */ + if (GET_CODE (old_val) == MEM) + old_val = force_reg (mode, old_val); + subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val, NULL_RTX, icode); if (subtarget == NULL_RTX) return NULL_RTX; - emit_cmp_insn (subtarget, new_val, EQ, const0_rtx, mode, true); + emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true); } /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a @@ -5700,7 +5705,7 @@ expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq) if (subtarget == NULL_RTX) return false; - emit_cmp_insn (subtarget, new_reg, EQ, const0_rtx, mode, true); + emit_cmp_insn (subtarget, old_reg, EQ, const0_rtx, mode, true); } /* ??? Mark this jump predicted not taken? */ @@ -5735,6 +5740,9 @@ expand_sync_operation (rtx mem, rtx val, enum rtx_code code) case AND: icode = sync_and_optab[mode]; break; + case NOT: + icode = sync_nand_optab[mode]; + break; case MINUS: icode = sync_sub_optab[mode]; @@ -5749,19 +5757,6 @@ expand_sync_operation (rtx mem, rtx val, enum rtx_code code) } break; - case NOT: - icode = sync_nand_optab[mode]; - if (icode == CODE_FOR_nothing) - { - icode = sync_and_optab[mode]; - if (icode != CODE_FOR_nothing) - { - val = expand_simple_unop (mode, NOT, val, NULL_RTX, 1); - code = AND; - } - } - break; - default: gcc_unreachable (); } @@ -5790,12 +5785,13 @@ expand_sync_operation (rtx mem, rtx val, enum rtx_code code) start_sequence (); + t1 = t0; if (code == NOT) { - val = expand_simple_unop (mode, NOT, val, NULL_RTX, true); + t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true); code = AND; } - t1 = expand_simple_binop (mode, code, t0, val, NULL_RTX, + t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true, OPTAB_LIB_WIDEN); insn = get_insns (); @@ -5842,6 +5838,10 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code, old_code = sync_old_and_optab[mode]; new_code = sync_new_and_optab[mode]; break; + case NOT: + old_code = sync_old_nand_optab[mode]; + new_code = sync_new_nand_optab[mode]; + break; case MINUS: old_code = sync_old_sub_optab[mode]; @@ -5858,21 +5858,6 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code, } break; - case NOT: - old_code = sync_old_nand_optab[mode]; - new_code = sync_new_nand_optab[mode]; - if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing) - { - old_code = sync_old_sub_optab[mode]; - new_code = sync_new_sub_optab[mode]; - if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing) - { - val = expand_simple_unop (mode, NOT, val, NULL_RTX, 1); - code = AND; - } - } - break; - default: gcc_unreachable (); } @@ -5933,6 +5918,9 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code, else if (code == MINUS) code = PLUS; } + + if (code == NOT) + target = expand_simple_unop (mode, NOT, target, NULL_RTX, true); target = expand_simple_binop (mode, code, target, val, NULL_RTX, true, OPTAB_LIB_WIDEN); } @@ -5952,14 +5940,15 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code, start_sequence (); + if (!after) + emit_move_insn (target, t0); + t1 = t0; if (code == NOT) { - val = expand_simple_unop (mode, NOT, val, NULL_RTX, true); + t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true); code = AND; } - if (!after) - emit_move_insn (target, t0); - t1 = expand_simple_binop (mode, code, t0, val, NULL_RTX, + t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true, OPTAB_LIB_WIDEN); if (after) emit_move_insn (target, t1); |