expr.c (expand_expr_unaligned): Add more code from full case that is needed when OP0 is in a register.

* expr.c (expand_expr_unaligned): Add more code from full case
	that is needed when OP0 is in a register.

From-SVN: r30712
This commit is contained in:
Richard Kenner 1999-11-29 22:35:51 +00:00 committed by Richard Kenner
parent b3bd782076
commit a2b9916174
2 changed files with 65 additions and 4 deletions

View File

@ -1,3 +1,8 @@
Mon Nov 29 16:56:42 1999 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (expand_expr_unaligned): Add more code from full case
that is needed when OP0 is in a register.
Mon Nov 29 18:09:39 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* dwarfout.c (field_byte_offset): Size can be zero if there was

View File

@ -8643,10 +8643,66 @@ expand_expr_unaligned (exp, palign)
TYPE_MODE (integer_type_node));
}
/* Get a reference to just this component. */
op0 = change_address (op0, mode1,
plus_constant (XEXP (op0, 0),
(bitpos / BITS_PER_UNIT)));
/* In cases where an aligned union has an unaligned object
as a field, we might be extracting a BLKmode value from
an integer-mode (e.g., SImode) object. Handle this case
by doing the extract into an object as wide as the field
(which we know to be the width of a basic mode), then
storing into memory, and changing the mode to BLKmode.
If we ultimately want the address (EXPAND_CONST_ADDRESS or
EXPAND_INITIALIZER), then we must not copy to a temporary. */
if (mode1 == VOIDmode
|| GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
|| (SLOW_UNALIGNED_ACCESS
&& (TYPE_ALIGN (type) > alignment * BITS_PER_UNIT
|| bitpos % TYPE_ALIGN (type) != 0)))
{
enum machine_mode ext_mode = mode_for_size (bitsize, MODE_INT, 1);
if (ext_mode == BLKmode)
{
/* In this case, BITPOS must start at a byte boundary. */
if (GET_CODE (op0) != MEM
|| bitpos % BITS_PER_UNIT != 0)
abort ();
op0 = change_address (op0, VOIDmode,
plus_constant (XEXP (op0, 0),
bitpos / BITS_PER_UNIT));
}
else
{
rtx new = assign_stack_temp (ext_mode,
bitsize / BITS_PER_UNIT, 0);
op0 = extract_bit_field (validize_mem (op0), bitsize, bitpos,
unsignedp, NULL_RTX, ext_mode,
ext_mode, alignment,
int_size_in_bytes (TREE_TYPE (tem)));
/* If the result is a record type and BITSIZE is narrower than
the mode of OP0, an integral mode, and this is a big endian
machine, we must put the field into the high-order bits. */
if (TREE_CODE (type) == RECORD_TYPE && BYTES_BIG_ENDIAN
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
&& bitsize < GET_MODE_BITSIZE (GET_MODE (op0)))
op0 = expand_shift (LSHIFT_EXPR, GET_MODE (op0), op0,
size_int (GET_MODE_BITSIZE
(GET_MODE (op0))
- bitsize),
op0, 1);
emit_move_insn (new, op0);
op0 = copy_rtx (new);
PUT_MODE (op0, BLKmode);
}
}
else
/* Get a reference to just this component. */
op0 = change_address (op0, mode1,
plus_constant (XEXP (op0, 0),
(bitpos / BITS_PER_UNIT)));
MEM_ALIAS_SET (op0) = get_alias_set (exp);