diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-07-23 01:21:31 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-07-23 01:21:31 +0000 |
commit | b234591528f63c31813f0e0101db64ce4ba607b0 (patch) | |
tree | dcae196cb9448ce862621b3d77db8a0bae222ce2 /gcc/explow.c | |
parent | a378632883e4ab2f8c4cb602ebed41b601cc980e (diff) | |
download | gcc-b234591528f63c31813f0e0101db64ce4ba607b0.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@28222 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/explow.c')
-rw-r--r-- | gcc/explow.c | 41 |
1 files changed, 41 insertions, 0 deletions
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; } |