From: Jim Wilson Date: Wed, 25 Oct 2000 01:30:25 +0000 (+0000) Subject: Fixes for C++ structure layout breakage. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a8ca77564609454aa4bad648471204640a55b300;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4c278bf412..6e87a789999 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2000-10-24 Jim Wilson + + * 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 * rtlanal.c (rtx_unstable_p, rtx_varies_p): Don't consider pic diff --git a/gcc/expmed.c b/gcc/expmed.c index 26050621561..254d052d8b5 100644 --- a/gcc/expmed.c +++ b/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. */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index ea9ee013dd7..797b4cea17d 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -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);