diff options
author | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-03-19 17:07:29 +0000 |
---|---|---|
committer | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-03-19 17:07:29 +0000 |
commit | a8bb7059514e2cfebe6ce6d866b9d27d9a4fb5d7 (patch) | |
tree | ddb2d551ea09bfec19c57fe8cc9e9c371f68943a /gcc/builtins.c | |
parent | 2dc9d68065ada66ead0f824018f1ad7af56f4cdc (diff) | |
download | gcc-a8bb7059514e2cfebe6ce6d866b9d27d9a4fb5d7.tar.gz |
* builtins.c (expand_builtin_sync_operation,
expand_builtin_compare_and_swap,
expand_builtin_lock_test_and_set): Care for extending CONST_INTs
correctly.
* config/i386/sync.md (sync_double_compare_and_swapdi_pic,
sync_double_compare_and_swap_ccdi_pic): Use "SD" as constraint
for operand 3.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123064 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 0bb148907cb..989b8d740b2 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5771,13 +5771,18 @@ expand_builtin_sync_operation (enum machine_mode mode, tree exp, rtx target, bool ignore) { rtx val, mem; + enum machine_mode old_mode; /* Expand the operands. */ mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL, mode, EXPAND_NORMAL); - /* If VAL is promoted to a wider mode, convert it back to MODE. */ - val = convert_to_mode (mode, val, 1); + /* If VAL is promoted to a wider mode, convert it back to MODE. Take care + of CONST_INTs, where we know the old_mode only from the call argument. */ + old_mode = GET_MODE (val); + if (old_mode == VOIDmode) + old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))); + val = convert_modes (mode, old_mode, val, 1); if (ignore) return expand_sync_operation (mem, val, code); @@ -5795,18 +5800,27 @@ expand_builtin_compare_and_swap (enum machine_mode mode, tree exp, bool is_bool, rtx target) { rtx old_val, new_val, mem; + enum machine_mode old_mode; /* Expand the operands. */ mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL, mode, EXPAND_NORMAL); - /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */ - old_val = convert_to_mode (mode, old_val, 1); + /* If VAL is promoted to a wider mode, convert it back to MODE. Take care + of CONST_INTs, where we know the old_mode only from the call argument. */ + old_mode = GET_MODE (old_val); + if (old_mode == VOIDmode) + old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))); + old_val = convert_modes (mode, old_mode, old_val, 1); new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL, mode, EXPAND_NORMAL); - /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */ - new_val = convert_to_mode (mode, new_val, 1); + /* If VAL is promoted to a wider mode, convert it back to MODE. Take care + of CONST_INTs, where we know the old_mode only from the call argument. */ + old_mode = GET_MODE (new_val); + if (old_mode == VOIDmode) + old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))); + new_val = convert_modes (mode, old_mode, new_val, 1); if (is_bool) return expand_bool_compare_and_swap (mem, old_val, new_val, target); @@ -5825,12 +5839,17 @@ expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp, rtx target) { rtx val, mem; + enum machine_mode old_mode; /* Expand the operands. */ mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL, mode, EXPAND_NORMAL); - /* If VAL is promoted to a wider mode, convert it back to MODE. */ - val = convert_to_mode (mode, val, 1); + /* If VAL is promoted to a wider mode, convert it back to MODE. Take care + of CONST_INTs, where we know the old_mode only from the call argument. */ + old_mode = GET_MODE (val); + if (old_mode == VOIDmode) + old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))); + val = convert_modes (mode, old_mode, val, 1); return expand_sync_lock_test_and_set (mem, val, target); } |