diff options
author | Michael Matz <matz@suse.de> | 2007-03-19 17:07:29 +0000 |
---|---|---|
committer | Michael Matz <matz@gcc.gnu.org> | 2007-03-19 17:07:29 +0000 |
commit | 1e395249a9f9be3050998a40aabf38e4fa863a37 (patch) | |
tree | ddb2d551ea09bfec19c57fe8cc9e9c371f68943a /gcc/builtins.c | |
parent | b5e5ca5fd3cba74accddb31d4b076686dbb271c1 (diff) | |
download | gcc-1e395249a9f9be3050998a40aabf38e4fa863a37.zip gcc-1e395249a9f9be3050998a40aabf38e4fa863a37.tar.gz gcc-1e395249a9f9be3050998a40aabf38e4fa863a37.tar.bz2 |
builtins.c (expand_builtin_sync_operation, [...]): Care for extending CONST_INTs correctly.
* 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.
From-SVN: r123064
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 0bb1489..989b8d7 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); } |