diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1996-03-16 18:56:24 -0500 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1996-03-16 18:56:24 -0500 |
commit | 9e74dc4154b83b504ba9382b4c68a19368c648b5 (patch) | |
tree | a0f6535276b72f2ee588190ae67454ed88187606 /gcc | |
parent | ff352ceaa015c25cba359d3261199e145a688872 (diff) | |
download | gcc-9e74dc4154b83b504ba9382b4c68a19368c648b5.zip gcc-9e74dc4154b83b504ba9382b4c68a19368c648b5.tar.gz gcc-9e74dc4154b83b504ba9382b4c68a19368c648b5.tar.bz2 |
(make_extraction): Correct typo in force_to_mode call in previous change.
Return 0 if pos+len out of range of want desired mode.
From-SVN: r11544
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/combine.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 7023119..70b9faa 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -5321,13 +5321,23 @@ make_extraction (mode, inner, pos, pos_rtx, len, } } - /* If INNER is not memory, we can always get it into the proper mode. */ + /* If INNER is not memory, we can always get it into the proper mode. If we + are changing its mode, POS must be a constant and smaller than the size + of the new mode. */ else if (GET_CODE (inner) != MEM) - inner = force_to_mode (inner, wanted_inner_mode, - pos_rtx || len + orig_pos >= HOST_BITS_PER_WIDE_INT - ? GET_MODE_MASK (extraction_mode) - : (((HOST_WIDE_INT) 1 << len) - 1) << orig_pos, - NULL_RTX, 0); + { + if (GET_MODE (inner) != wanted_inner_mode + && (pos_rtx != 0 + || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode))) + return 0; + + inner = force_to_mode (inner, wanted_inner_mode, + pos_rtx + || len + orig_pos >= HOST_BITS_PER_WIDE_INT + ? GET_MODE_MASK (wanted_inner_mode) + : (((HOST_WIDE_INT) 1 << len) - 1) << orig_pos, + NULL_RTX, 0); + } /* Adjust mode of POS_RTX, if needed. If we want a wider mode, we have to zero extend. Otherwise, we can just use a SUBREG. */ |