aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2007-03-19 17:07:29 +0000
committerMichael Matz <matz@gcc.gnu.org>2007-03-19 17:07:29 +0000
commit1e395249a9f9be3050998a40aabf38e4fa863a37 (patch)
treeddb2d551ea09bfec19c57fe8cc9e9c371f68943a /gcc/builtins.c
parentb5e5ca5fd3cba74accddb31d4b076686dbb271c1 (diff)
downloadgcc-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.c35
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);
}