aboutsummaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-10-29 17:07:39 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2008-10-29 17:07:39 +0100
commit7d293b587a78e9a779620da1519fab0c577de19a (patch)
tree21f02a1ca2098a2e0f7ed9fdcbc9e7e08831ede5 /gcc/expmed.c
parentd3f7b2c67ed130a856a1d7425e76d69d47bb6006 (diff)
downloadgcc-7d293b587a78e9a779620da1519fab0c577de19a.zip
gcc-7d293b587a78e9a779620da1519fab0c577de19a.tar.gz
gcc-7d293b587a78e9a779620da1519fab0c577de19a.tar.bz2
re PR middle-end/37870 (ICE in extract_bit_field_1)
PR middle-end/37870 * expmed.c (extract_bit_field_1): If int_mode_for_mode returns BLKmode for non-memory, convert using a wider MODE_INT mode or through memory. * gcc.target/i386/pr37870.c: New test. From-SVN: r141430
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 5e8d7f3..0c7e611 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -1,7 +1,7 @@
/* Medium-level subroutines: convert bit-field store and extract
and shifts, multiplies and divides to rtl instructions.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -1278,9 +1278,8 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
{
if (MEM_P (op0))
op0 = adjust_address (op0, imode, 0);
- else
+ else if (imode != BLKmode)
{
- gcc_assert (imode != BLKmode);
op0 = gen_lowpart (imode, op0);
/* If we got a SUBREG, force it into a register since we
@@ -1288,6 +1287,24 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
if (GET_CODE (op0) == SUBREG)
op0 = force_reg (imode, op0);
}
+ else if (REG_P (op0))
+ {
+ rtx reg, subreg;
+ imode = smallest_mode_for_size (GET_MODE_BITSIZE (GET_MODE (op0)),
+ MODE_INT);
+ reg = gen_reg_rtx (imode);
+ subreg = gen_lowpart_SUBREG (GET_MODE (op0), reg);
+ emit_move_insn (subreg, op0);
+ op0 = reg;
+ bitnum += SUBREG_BYTE (subreg) * BITS_PER_UNIT;
+ }
+ else
+ {
+ rtx mem = assign_stack_temp (GET_MODE (op0),
+ GET_MODE_SIZE (GET_MODE (op0)), 0);
+ emit_move_insn (mem, op0);
+ op0 = adjust_address (mem, BLKmode, 0);
+ }
}
}