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:
Jim Wilson 2000-10-25 01:30:25 +00:00 committed by Jim Wilson
parent c0fc376bcf
commit a8ca775646
3 changed files with 29 additions and 23 deletions

View File

@ -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

View File

@ -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. */

View File

@ -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);