diff options
author | Richard Henderson <rth@cygnus.com> | 1998-10-13 16:06:47 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1998-10-13 16:06:47 -0700 |
commit | 470032d72e41bac5ed47efd297dbe9d0ec5d3dc8 (patch) | |
tree | d3ddc0423dc067ad1caff6982ac81cd14c03a0fe | |
parent | 73aeb2ff9b05da69dd92ad674608df424252593c (diff) | |
download | gcc-470032d72e41bac5ed47efd297dbe9d0ec5d3dc8.zip gcc-470032d72e41bac5ed47efd297dbe9d0ec5d3dc8.tar.gz gcc-470032d72e41bac5ed47efd297dbe9d0ec5d3dc8.tar.bz2 |
function.c (purge_addressof_1): Fix typo in inequality: do bitfield optimization for equal mode sizes.
* function.c (purge_addressof_1): Fix typo in inequality: do
bitfield optimization for equal mode sizes.
* expmed.c (store_bit_field): Don't take subregs of subregs in
the movstrict case. Tidy a potential problem in the multi-word case.
(extract_bit_field): Likewise.
From-SVN: r23066
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/expmed.c | 36 | ||||
-rw-r--r-- | gcc/function.c | 2 |
3 files changed, 38 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c21fd3..e6e5dab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Tue Oct 13 23:03:37 1998 Richard Henderson <rth@cygnus.com> + + * function.c (purge_addressof_1): Fix typo in inequality: do + bitfield optimization for equal mode sizes. + * expmed.c (store_bit_field): Don't take subregs of subregs in + the movstrict case. Tidy a potential problem in the multi-word case. + (extract_bit_field): Likewise. + Tue Oct 13 22:12:11 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * flow.c (find_basic_blocks): Emit NOPs after normal calls in this diff --git a/gcc/expmed.c b/gcc/expmed.c index bb222456..1c9fcf5 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -347,8 +347,22 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) else { int icode = movstrict_optab->handlers[(int) fieldmode].insn_code; - if(! (*insn_operand_predicate[icode][1]) (value, fieldmode)) + if (! (*insn_operand_predicate[icode][1]) (value, fieldmode)) value = copy_to_mode_reg (fieldmode, value); + + if (GET_CODE (op0) == SUBREG) + { + if (GET_MODE (SUBREG_REG (op0)) == fieldmode + || GET_MODE_CLASS (fieldmode) == MODE_INT + || GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT) + op0 = SUBREG_REG (op0); + else + /* Else we've got some float mode source being extracted into + a different float mode destination -- this combination of + subregs results in Severe Tire Damage. */ + abort (); + } + emit_insn (GEN_FCN (icode) (gen_rtx_SUBREG (fieldmode, op0, offset), value)); } @@ -403,12 +417,16 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) /* OFFSET is the number of words or bytes (UNIT says which) from STR_RTX to the first word or byte containing part of the field. */ - if (GET_CODE (op0) == REG) + if (GET_CODE (op0) != MEM) { if (offset != 0 || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD) - op0 = gen_rtx_SUBREG (TYPE_MODE (type_for_size (BITS_PER_WORD, 0)), - op0, offset); + { + if (GET_CODE (op0) != REG) + op0 = copy_to_reg (op0); + op0 = gen_rtx_SUBREG (mode_for_size (BITS_PER_WORD, MODE_INT, 0), + op0, offset); + } offset = 0; } else @@ -539,7 +557,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) { /* Avoid making subreg of a subreg, or of a mem. */ if (GET_CODE (value1) != REG) - value1 = copy_to_reg (value1); + value1 = copy_to_reg (value1); value1 = gen_rtx_SUBREG (maxmode, value1, 0); } else @@ -1146,8 +1164,12 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, { if (offset != 0 || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD) - op0 = gen_rtx_SUBREG (mode_for_size (BITS_PER_WORD, MODE_INT, 0), - op0, offset); + { + if (GET_CODE (op0) != REG) + op0 = copy_to_reg (op0); + op0 = gen_rtx_SUBREG (mode_for_size (BITS_PER_WORD, MODE_INT, 0), + op0, offset); + } offset = 0; } else diff --git a/gcc/function.c b/gcc/function.c index 48018cf..3904b86 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2885,7 +2885,7 @@ purge_addressof_1 (loc, insn, force, store) /* Don't even consider working with paradoxical subregs, or the moral equivalent seen here. */ - if (size_x < size_sub + if (size_x <= size_sub && int_mode_for_mode (GET_MODE (sub)) != BLKmode) { /* Do a bitfield insertion to mirror what would happen |