Additional code in expand_expr_unaligned
Richard Kenner
kenner@vlsi1.ultra.nyu.edu
Mon Nov 29 14:41:00 GMT 1999
I just committed this patch (which is safe, since the new code does
things where the old code would have aborted).
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.
*** expr.c.nov28 Sun Nov 28 08:46:31 1999
--- expr.c Sun Nov 28 10:27:35 1999
*************** expand_expr_unaligned (exp, palign)
*** 7855,7862 ****
}
! /* Get a reference to just this component. */
! op0 = change_address (op0, mode1,
! plus_constant (XEXP (op0, 0),
! (bitpos / BITS_PER_UNIT)));
/* Adjust the alignment in case the bit position is not
--- 7860,7923 ----
}
! /* 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)));
/* Adjust the alignment in case the bit position is not
More information about the Gcc-patches
mailing list