Commit 7e4ce834 by Richard Henderson Committed by Richard Henderson

explow.c (trunc_int_for_mode): New function.

        * explow.c (trunc_int_for_mode): New function.
        (plus_constant_wide): Use it.
        * combine.c (simplify_and_const_int): Likewise.
        (merge_outer_ops): Likewise.
        (simplify_shift_const): Likewise.
        * cse.c (simplify_unary_operation): Likewise.
        (simplify_binary_operation): Likewise.
        * emit-rtl.c (operand_subword): Likewise.
        * rtl.h: Declare it.

From-SVN: r28222
parent 27b8d0cd
Thu Jul 22 18:21:04 1999 Richard Henderson <rth@cygnus.com>
* explow.c (trunc_int_for_mode): New function.
(plus_constant_wide): Use it.
* combine.c (simplify_and_const_int): Likewise.
(merge_outer_ops): Likewise.
(simplify_shift_const): Likewise.
* cse.c (simplify_unary_operation): Likewise.
(simplify_binary_operation): Likewise.
* emit-rtl.c (operand_subword): Likewise.
* rtl.h: Declare it.
Thu Jul 22 14:34:59 1999 Bernd Schmidt <bernds@cygnus.co.uk> Thu Jul 22 14:34:59 1999 Bernd Schmidt <bernds@cygnus.co.uk>
* config/arm/arm.c (arm_print_operand): Fix typo in 'M' case * config/arm/arm.c (arm_print_operand): Fix typo in 'M' case
......
...@@ -7336,19 +7336,7 @@ simplify_and_const_int (x, mode, varop, constop) ...@@ -7336,19 +7336,7 @@ simplify_and_const_int (x, mode, varop, constop)
MODE. */ MODE. */
nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode); nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode);
nonzero = trunc_int_for_mode (nonzero, mode);
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (nonzero & ((HOST_WIDE_INT) 1 << (width - 1))))
nonzero |= ((HOST_WIDE_INT) (-1) << width);
/* Turn off all bits in the constant that are known to already be zero. /* Turn off all bits in the constant that are known to already be zero.
Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS
...@@ -8327,18 +8315,10 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p) ...@@ -8327,18 +8315,10 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
&& op0 == AND) && op0 == AND)
op0 = NIL; op0 = NIL;
/* If this would be an entire word for the target, but is not for /* ??? Slightly redundant with the above mask, but not entirely.
the host, then sign-extend on the host so that the number will look Moving this above means we'd have to sign-extend the mode mask
the same way on the host that it would on the target. for the final test. */
const0 = trunc_int_for_mode (const0, mode);
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (const0 & ((HOST_WIDE_INT) 1 << (width - 1))))
const0 |= ((HOST_WIDE_INT) (-1) << width);
*pop0 = op0; *pop0 = op0;
*pconst0 = const0; *pconst0 = const0;
...@@ -9053,24 +9033,7 @@ simplify_shift_const (x, code, result_mode, varop, count) ...@@ -9053,24 +9033,7 @@ simplify_shift_const (x, code, result_mode, varop, count)
if (outer_op != NIL) if (outer_op != NIL)
{ {
if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT) if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT)
{ outer_const = trunc_int_for_mode (outer_const, result_mode);
int width = GET_MODE_BITSIZE (result_mode);
outer_const &= GET_MODE_MASK (result_mode);
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will
look the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (outer_const & ((HOST_WIDE_INT) 1 << (width - 1))))
outer_const |= ((HOST_WIDE_INT) (-1) << width);
}
if (outer_op == AND) if (outer_op == AND)
x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const); x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const);
......
...@@ -3364,27 +3364,7 @@ simplify_unary_operation (code, mode, op, op_mode) ...@@ -3364,27 +3364,7 @@ simplify_unary_operation (code, mode, op, op_mode)
abort (); abort ();
} }
/* Clear the bits that don't belong in our mode, val = trunc_int_for_mode (val, mode);
unless they and our sign bit are all one.
So we get either a reasonable negative value or a reasonable
unsigned value for this mode. */
if (width < HOST_BITS_PER_WIDE_INT
&& ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
!= ((HOST_WIDE_INT) (-1) << (width - 1))))
val &= ((HOST_WIDE_INT) 1 << width) - 1;
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (val & ((HOST_WIDE_INT) 1 << (width - 1))))
val |= ((HOST_WIDE_INT) (-1) << width);
return GEN_INT (val); return GEN_INT (val);
} }
...@@ -3556,27 +3536,7 @@ simplify_unary_operation (code, mode, op, op_mode) ...@@ -3556,27 +3536,7 @@ simplify_unary_operation (code, mode, op, op_mode)
set_float_handler (NULL_PTR); set_float_handler (NULL_PTR);
/* Clear the bits that don't belong in our mode, val = trunc_int_for_mode (val, mode);
unless they and our sign bit are all one.
So we get either a reasonable negative value or a reasonable
unsigned value for this mode. */
if (width < HOST_BITS_PER_WIDE_INT
&& ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
!= ((HOST_WIDE_INT) (-1) << (width - 1))))
val &= ((HOST_WIDE_INT) 1 << width) - 1;
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (val & ((HOST_WIDE_INT) 1 << (width - 1))))
val |= ((HOST_WIDE_INT) (-1) << width);
return GEN_INT (val); return GEN_INT (val);
} }
...@@ -4458,26 +4418,7 @@ simplify_binary_operation (code, mode, op0, op1) ...@@ -4458,26 +4418,7 @@ simplify_binary_operation (code, mode, op0, op1)
abort (); abort ();
} }
/* Clear the bits that don't belong in our mode, unless they and our sign val = trunc_int_for_mode (val, mode);
bit are all one. So we get either a reasonable negative value or a
reasonable unsigned value for this mode. */
if (width < HOST_BITS_PER_WIDE_INT
&& ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
!= ((HOST_WIDE_INT) (-1) << (width - 1))))
val &= ((HOST_WIDE_INT) 1 << width) - 1;
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (val & ((HOST_WIDE_INT) 1 << (width - 1))))
val |= ((HOST_WIDE_INT) (-1) << width);
return GEN_INT (val); return GEN_INT (val);
} }
......
...@@ -1489,26 +1489,7 @@ operand_subword (op, i, validate_address, mode) ...@@ -1489,26 +1489,7 @@ operand_subword (op, i, validate_address, mode)
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT) if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT)
val = ((val >> ((i % size_ratio) * BITS_PER_WORD))); val = ((val >> ((i % size_ratio) * BITS_PER_WORD)));
/* Clear the bits that don't belong in our mode, unless they and our sign val = trunc_int_for_mode (val, word_mode);
bit are all one. So we get either a reasonable negative value or a
reasonable unsigned value for this mode. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT
&& ((val & ((HOST_WIDE_INT) (-1) << (bits_per_word - 1)))
!= ((HOST_WIDE_INT) (-1) << (bits_per_word - 1))))
val &= ((HOST_WIDE_INT) 1 << bits_per_word) - 1;
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT
&& (val & ((HOST_WIDE_INT) 1 << (bits_per_word - 1))))
val |= ((HOST_WIDE_INT) (-1) << bits_per_word);
return GEN_INT (val); return GEN_INT (val);
} }
......
...@@ -38,6 +38,43 @@ Boston, MA 02111-1307, USA. */ ...@@ -38,6 +38,43 @@ Boston, MA 02111-1307, USA. */
static rtx break_out_memory_refs PROTO((rtx)); static rtx break_out_memory_refs PROTO((rtx));
static void emit_stack_probe PROTO((rtx)); static void emit_stack_probe PROTO((rtx));
/* Truncate and perhaps sign-extend C as appropriate for MODE. */
HOST_WIDE_INT
trunc_int_for_mode (c, mode)
HOST_WIDE_INT c;
enum machine_mode mode;
{
int width = GET_MODE_BITSIZE (mode);
/* We clear out all bits that don't belong in MODE, unless they and our
sign bit are all one. So we get either a reasonable negative
value or a reasonable unsigned value. */
if (width < HOST_BITS_PER_WIDE_INT
&& ((c & ((HOST_WIDE_INT) (-1) << (width - 1)))
!= ((HOST_WIDE_INT) (-1) << (width - 1))))
c &= ((HOST_WIDE_INT) 1 << width) - 1;
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT
&& BITS_PER_WORD == width
&& (c & ((HOST_WIDE_INT) 1 << (width - 1))))
c |= ((HOST_WIDE_INT) (-1) << width);
return c;
}
/* Return an rtx for the sum of X and the integer C. /* Return an rtx for the sum of X and the integer C.
This function should be used via the `plus_constant' macro. */ This function should be used via the `plus_constant' macro. */
...@@ -126,6 +163,10 @@ plus_constant_wide (x, c) ...@@ -126,6 +163,10 @@ plus_constant_wide (x, c)
if (GET_CODE (XEXP (x, 1)) == CONST_INT) if (GET_CODE (XEXP (x, 1)) == CONST_INT)
{ {
c += INTVAL (XEXP (x, 1)); c += INTVAL (XEXP (x, 1));
if (GET_MODE (x) != VOIDmode)
c = trunc_int_for_mode (c, GET_MODE (x));
x = XEXP (x, 0); x = XEXP (x, 0);
goto restart; goto restart;
} }
......
...@@ -909,6 +909,8 @@ extern int ceil_log2 PROTO((unsigned HOST_WIDE_INT)); ...@@ -909,6 +909,8 @@ extern int ceil_log2 PROTO((unsigned HOST_WIDE_INT));
plus_constant_for_output_wide (X, (HOST_WIDE_INT) (C)) plus_constant_for_output_wide (X, (HOST_WIDE_INT) (C))
/* In explow.c */ /* In explow.c */
extern HOST_WIDE_INT trunc_int_for_mode PROTO((HOST_WIDE_INT,
enum machine_mode));
extern rtx plus_constant_wide PROTO((rtx, HOST_WIDE_INT)); extern rtx plus_constant_wide PROTO((rtx, HOST_WIDE_INT));
extern rtx plus_constant_for_output_wide PROTO((rtx, HOST_WIDE_INT)); extern rtx plus_constant_for_output_wide PROTO((rtx, HOST_WIDE_INT));
extern void optimize_save_area_alloca PROTO((rtx)); extern void optimize_save_area_alloca PROTO((rtx));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment