mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-18 08:23:50 +08:00
Fixes for C++ structure layout breakage.
* expmed.c (store_bit_field): Move integer pun code down after code that calls emit_move_insn for entire register move. * stor-layout.c (compute_record_mode): Revert Mar 25, Aug 18, and Oct 20 changes. Only store mode in TYPE_MODE if RECORD_TYPE. From-SVN: r37041
This commit is contained in:
parent
c0fc376bcf
commit
a8ca775646
@ -1,3 +1,10 @@
|
||||
2000-10-24 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* expmed.c (store_bit_field): Move integer pun code down after
|
||||
code that calls emit_move_insn for entire register move.
|
||||
* stor-layout.c (compute_record_mode): Revert Mar 25, Aug 18, and
|
||||
Oct 20 changes. Only store mode in TYPE_MODE if RECORD_TYPE.
|
||||
|
||||
2000-10-24 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* rtlanal.c (rtx_unstable_p, rtx_varies_p): Don't consider pic
|
||||
|
32
gcc/expmed.c
32
gcc/expmed.c
@ -269,21 +269,6 @@ 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. */
|
||||
@ -337,6 +322,23 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Make sure we are playing with integral modes. Pun with subregs
|
||||
if we aren't. This must come after the entire register case above,
|
||||
since that case is valid for any mode. The following cases are only
|
||||
valid for integral modes. */
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Storing an lsb-aligned field in a register
|
||||
can be done with a movestrict instruction. */
|
||||
|
||||
|
@ -1065,12 +1065,8 @@ compute_record_mode (type)
|
||||
|
||||
/* If this field is the whole struct, remember its mode so
|
||||
that, say, we can put a double in a class into a DF
|
||||
register instead of forcing it to live in the stack. However,
|
||||
we don't support using such a mode if there is no integer mode
|
||||
of the same size, so don't set it here. */
|
||||
if (field == TYPE_FIELDS (type) && TREE_CHAIN (field) == 0
|
||||
&& int_mode_for_mode (DECL_MODE (field)) != BLKmode
|
||||
&& operand_equal_p (DECL_SIZE (field), TYPE_SIZE (type), 1))
|
||||
register instead of forcing it to live in the stack. */
|
||||
if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
|
||||
mode = DECL_MODE (field);
|
||||
|
||||
#ifdef STRUCT_FORCE_BLK
|
||||
@ -1081,8 +1077,9 @@ compute_record_mode (type)
|
||||
#endif /* STRUCT_FORCE_BLK */
|
||||
}
|
||||
|
||||
if (mode != VOIDmode)
|
||||
/* We only have one real field; use its mode. */
|
||||
/* If we only have one real field; use its mode. This only applies to
|
||||
RECORD_TYPE. This does not apply to unions. */
|
||||
if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode)
|
||||
TYPE_MODE (type) = mode;
|
||||
else
|
||||
TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user