diff options
author | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-05-06 19:47:15 +0000 |
---|---|---|
committer | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-05-06 19:47:15 +0000 |
commit | 0dc08e9712c7516030972d73a473b4d477edbbdd (patch) | |
tree | f51487f0e2aa2816e161b63bfa5e94383466bc0d /gcc/optabs.c | |
parent | a34a600b781d00c03684c5404c8b57a034950c7e (diff) | |
download | gcc-0dc08e9712c7516030972d73a473b4d477edbbdd.tar.gz |
* optabs.c (expand_binop): Sign-extend xop0 and xop1 from the
widest mode in narrowing and widening operations.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41885 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 4068fa863db..c6da81592fd 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -725,13 +725,20 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) /* In case the insn wants input operands in modes different from the result, convert the operands. It would seem that we don't need to convert CONST_INTs, but we do, so that they're - a properly sign-extended for their modes. */ + a properly sign-extended for their modes; we choose the + widest mode between mode and mode[01], so that, in a widening + operation, we call convert_modes with different FROM and TO + modes, which ensures the value is sign-extended. Shift + operations are an exception, because the second operand needs + not be extended to the mode of the result. */ if (GET_MODE (op0) != mode0 && mode0 != VOIDmode) xop0 = convert_modes (mode0, GET_MODE (op0) != VOIDmode ? GET_MODE (op0) + : GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode0) + ? mode : mode0, xop0, unsignedp); @@ -740,6 +747,9 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) xop1 = convert_modes (mode1, GET_MODE (op1) != VOIDmode ? GET_MODE (op1) + : (GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode1) + && ! shift_op) + ? mode : mode1, xop1, unsignedp); |