Commit d006aa54 by Richard Henderson Committed by Richard Henderson

expmed.c (store_bit_field): Pun non-integral str_rtx modes.

        * expmed.c (store_bit_field): Pun non-integral str_rtx modes.
        Take extra care for op0 now possibly being a subreg.
        (extract_bit_field): Likewise.
        * function.c (purge_addressof_1): Revert Oct 4 change.  Drop
        the reg to memory if there is no equal sized integral mode.
        * stor-layout.c (int_mode_for_mode): New function.
        * machmode.h: Prototype it.

From-SVN: r22962
parent 3663a304
Fri Oct 9 15:49:29 1998 Richard Henderson <rth@cygnus.com>
* expmed.c (store_bit_field): Pun non-integral str_rtx modes.
Take extra care for op0 now possibly being a subreg.
(extract_bit_field): Likewise.
* function.c (purge_addressof_1): Revert Oct 4 change. Drop
the reg to memory if there is no equal sized integral mode.
* stor-layout.c (int_mode_for_mode): New function.
* machmode.h: Prototype it.
Fri Oct 9 14:26:44 1998 Jeffrey A Law (law@cygnus.com)
* global.c (build_insn_chain): Verify no real insns exist past the
......
......@@ -261,6 +261,21 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
op0 = SUBREG_REG (op0);
}
/* Make sure we are playing with integral modes. Pun with subregs
if we aren't. */
{
enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
if (imode != GET_MODE (op0))
{
if (GET_CODE (op0) == MEM)
op0 = change_address (op0, imode, NULL_RTX);
else if (imode != BLKmode)
op0 = gen_lowpart (imode, op0);
else
abort ();
}
}
/* If OP0 is a register, BITPOS must count within a word.
But as we have it, it counts within whatever size OP0 now has.
On a bigendian machine, these are not the same, so convert. */
......@@ -287,6 +302,18 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
can be done with just SUBREG. */
if (GET_MODE (op0) != fieldmode)
{
if (GET_CODE (op0) == SUBREG)
{
if (GET_MODE (SUBREG_REG (op0)) == fieldmode
|| GET_MODE_CLASS (fieldmode) == MODE_INT
|| GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT)
op0 = SUBREG_REG (op0);
else
/* Else we've got some float mode source being extracted into
a different float mode destination -- this combination of
subregs results in Severe Tire Damage. */
abort ();
}
if (GET_CODE (op0) == REG)
op0 = gen_rtx_SUBREG (fieldmode, op0, offset);
else
......@@ -955,6 +982,21 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
op0 = SUBREG_REG (op0);
}
/* Make sure we are playing with integral modes. Pun with subregs
if we aren't. */
{
enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
if (imode != GET_MODE (op0))
{
if (GET_CODE (op0) == MEM)
op0 = change_address (op0, imode, NULL_RTX);
else if (imode != BLKmode)
op0 = gen_lowpart (imode, op0);
else
abort ();
}
}
/* ??? We currently assume TARGET is at least as big as BITSIZE.
If that's wrong, the solution is to test for it and set TARGET to 0
if needed. */
......@@ -973,7 +1015,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
So too extracting a subword value in
the least significant part of the register. */
if (((GET_CODE (op0) == REG
if (((GET_CODE (op0) != MEM
&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (GET_MODE (op0))))
|| (GET_CODE (op0) == MEM
......@@ -996,6 +1038,18 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
if (mode1 != GET_MODE (op0))
{
if (GET_CODE (op0) == SUBREG)
{
if (GET_MODE (SUBREG_REG (op0)) == mode1
|| GET_MODE_CLASS (mode1) == MODE_INT
|| GET_MODE_CLASS (mode1) == MODE_PARTIAL_INT)
op0 = SUBREG_REG (op0);
else
/* Else we've got some float mode source being extracted into
a different float mode destination -- this combination of
subregs results in Severe Tire Damage. */
abort ();
}
if (GET_CODE (op0) == REG)
op0 = gen_rtx_SUBREG (mode1, op0, offset);
else
......@@ -1088,11 +1142,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
/* OFFSET is the number of words or bytes (UNIT says which)
from STR_RTX to the first word or byte containing part of the field. */
if (GET_CODE (op0) == REG)
if (GET_CODE (op0) != MEM)
{
if (offset != 0
|| GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
op0 = gen_rtx_SUBREG (TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
op0 = gen_rtx_SUBREG (mode_for_size (BITS_PER_WORD, MODE_INT, 0),
op0, offset);
offset = 0;
}
......
......@@ -2874,24 +2874,14 @@ purge_addressof_1 (loc, insn, force, store)
/* Don't even consider working with paradoxical subregs,
or the moral equivalent seen here. */
if (size_x < size_sub)
if (size_x < size_sub
&& int_mode_for_mode (GET_MODE (sub)) != BLKmode)
{
/* Do a bitfield insertion to mirror what would happen
in memory. */
rtx val, seq;
/* We cannot do this if we are trying to pick out
an integral piece, smaller than a word, of a
floating point value. */
if (INTEGRAL_MODE_P (GET_MODE (x))
&& GET_MODE_SIZE (GET_MODE (x)) < UNITS_PER_WORD
&& FLOAT_MODE_P (GET_MODE (sub)))
{
put_addressof_into_stack (XEXP (x, 0));
return;
}
if (store)
{
/* If we can't replace with a register, be afraid. */
......
......@@ -211,6 +211,11 @@ extern unsigned char mode_wider_mode[];
extern enum machine_mode mode_for_size PROTO((unsigned int, enum mode_class, int));
/* Return an integer mode of the exact same size as the input mode,
or BLKmode on failure. */
extern enum machine_mode int_mode_for_mode PROTO((enum machine_mode));
/* Find the best mode to use to access a bit field. */
extern enum machine_mode get_best_mode PROTO((int, int, int, enum machine_mode, int));
......
......@@ -176,6 +176,37 @@ smallest_mode_for_size (size, class)
abort ();
}
/* Find an integer mode of the exact same size, or BLKmode on failure. */
enum machine_mode
int_mode_for_mode (mode)
enum machine_mode mode;
{
switch (GET_MODE_CLASS (mode))
{
case MODE_INT:
case MODE_PARTIAL_INT:
break;
case MODE_COMPLEX_INT:
case MODE_COMPLEX_FLOAT:
case MODE_FLOAT:
mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
break;
case MODE_RANDOM:
if (mode == BLKmode)
break;
/* FALLTHRU */
case MODE_CC:
default:
abort();
}
return mode;
}
/* Return the value of VALUE, rounded up to a multiple of DIVISOR. */
tree
......
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