From 7e4ce834b2867f4c7bb2b44e434f5d2778e23ca3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 22 Jul 1999 18:21:31 -0700 Subject: [PATCH] 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 --- gcc/ChangeLog | 12 ++++++++++ gcc/combine.c | 49 +++++-------------------------------- gcc/cse.c | 65 +++----------------------------------------------- gcc/emit-rtl.c | 21 +--------------- gcc/explow.c | 41 +++++++++++++++++++++++++++++++ gcc/rtl.h | 2 ++ 6 files changed, 65 insertions(+), 125 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ce5ddaea9ce..8f24efcf2a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Thu Jul 22 18:21:04 1999 Richard Henderson + + * 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 * config/arm/arm.c (arm_print_operand): Fix typo in 'M' case diff --git a/gcc/combine.c b/gcc/combine.c index 60e0ef27efc..c9736e5e56c 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7336,19 +7336,7 @@ simplify_and_const_int (x, mode, varop, constop) MODE. */ nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (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); + nonzero = trunc_int_for_mode (nonzero, mode); /* 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 @@ -8327,18 +8315,10 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p) && op0 == AND) op0 = NIL; - /* 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 - && (const0 & ((HOST_WIDE_INT) 1 << (width - 1)))) - const0 |= ((HOST_WIDE_INT) (-1) << width); + /* ??? Slightly redundant with the above mask, but not entirely. + Moving this above means we'd have to sign-extend the mode mask + for the final test. */ + const0 = trunc_int_for_mode (const0, mode); *pop0 = op0; *pconst0 = const0; @@ -9053,24 +9033,7 @@ simplify_shift_const (x, code, result_mode, varop, count) if (outer_op != NIL) { if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT) - { - 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); - } + outer_const = trunc_int_for_mode (outer_const, result_mode); if (outer_op == AND) x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const); diff --git a/gcc/cse.c b/gcc/cse.c index 605d1850753..edd434b5395 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -3364,27 +3364,7 @@ simplify_unary_operation (code, mode, op, op_mode) abort (); } - /* Clear the bits that don't belong in our 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); + val = trunc_int_for_mode (val, mode); return GEN_INT (val); } @@ -3556,27 +3536,7 @@ simplify_unary_operation (code, mode, op, op_mode) set_float_handler (NULL_PTR); - /* Clear the bits that don't belong in our 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); + val = trunc_int_for_mode (val, mode); return GEN_INT (val); } @@ -4458,26 +4418,7 @@ simplify_binary_operation (code, mode, op0, op1) abort (); } - /* Clear the bits that don't belong in our 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); + val = trunc_int_for_mode (val, mode); return GEN_INT (val); } diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 4519a23b5af..de0262c04bf 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1489,26 +1489,7 @@ operand_subword (op, i, validate_address, mode) if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT) val = ((val >> ((i % size_ratio) * BITS_PER_WORD))); - /* Clear the bits that don't belong in our 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 (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); + val = trunc_int_for_mode (val, word_mode); return GEN_INT (val); } diff --git a/gcc/explow.c b/gcc/explow.c index f06d99214e1..92f99ad65f2 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -38,6 +38,43 @@ Boston, MA 02111-1307, USA. */ static rtx break_out_memory_refs 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. This function should be used via the `plus_constant' macro. */ @@ -126,6 +163,10 @@ plus_constant_wide (x, c) if (GET_CODE (XEXP (x, 1)) == CONST_INT) { c += INTVAL (XEXP (x, 1)); + + if (GET_MODE (x) != VOIDmode) + c = trunc_int_for_mode (c, GET_MODE (x)); + x = XEXP (x, 0); goto restart; } diff --git a/gcc/rtl.h b/gcc/rtl.h index 8eba5eab5d9..520fa820898 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -909,6 +909,8 @@ extern int ceil_log2 PROTO((unsigned HOST_WIDE_INT)); plus_constant_for_output_wide (X, (HOST_WIDE_INT) (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_for_output_wide PROTO((rtx, HOST_WIDE_INT)); extern void optimize_save_area_alloca PROTO((rtx)); -- 2.30.2