summaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-20 04:54:11 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-20 04:54:11 +0000
commit87121034113f8b3bb96db325d3260d806f4e103a (patch)
tree4acdd6c4898d643fa0b840941a2d12315366ec66 /gcc/optabs.c
parent039f212de27c41c806d96f52be4b534138dbfc10 (diff)
downloadgcc-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.c61
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);