diff options
author | Jim Wilson <wilson@cygnus.com> | 2000-10-25 01:30:25 +0000 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 2000-10-24 18:30:25 -0700 |
commit | a8ca77564609454aa4bad648471204640a55b300 (patch) | |
tree | 9642e7e20204571cf15e101b98b0af82637ce77f /gcc | |
parent | c0fc376bcfaaf42823c07e5cd8420343fd56b370 (diff) | |
download | gcc-a8ca77564609454aa4bad648471204640a55b300.zip gcc-a8ca77564609454aa4bad648471204640a55b300.tar.gz gcc-a8ca77564609454aa4bad648471204640a55b300.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/expmed.c | 32 | ||||
-rw-r--r-- | gcc/stor-layout.c | 13 |
3 files changed, 29 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4c278b..6e87a78 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/expmed.c b/gcc/expmed.c index 2605062..254d052 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 ea9ee01..797b4ce 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); |