aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoff Keating <geoffk@cygnus.com>1999-10-26 06:48:38 +0000
committerJeff Law <law@gcc.gnu.org>1999-10-26 00:48:38 -0600
commit3306eb80e9693133e9a7c5e37ab59e8d8405ea4e (patch)
tree18f833dbd6567db4a4f6a65c35f9a900a031ab95
parent543c94cc93c326c0892fb36f248f7d8b11dc2f83 (diff)
downloadgcc-3306eb80e9693133e9a7c5e37ab59e8d8405ea4e.zip
gcc-3306eb80e9693133e9a7c5e37ab59e8d8405ea4e.tar.gz
gcc-3306eb80e9693133e9a7c5e37ab59e8d8405ea4e.tar.bz2
expmed.c (extract_bit_field): Allow for the case of non-integer objects that are smaller than a word (like...
* expmed.c (extract_bit_field): Allow for the case of non-integer objects that are smaller than a word (like SFmode on a 64-bit machine). From-SVN: r30185
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/expmed.c30
2 files changed, 24 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5416ab4..24f2e3e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -6,6 +6,10 @@ Tue Oct 26 00:41:54 1999 Bernd Schmidt <bernds@cygnus.co.uk>
Mon Oct 25 23:54:45 1999 Geoff Keating <geoffk@cygnus.com>
+ * expmed.c (extract_bit_field): Allow for the case of non-integer
+ objects that are smaller than a word (like SFmode on a 64-bit
+ machine).
+
* loop.c (basic_induction_var): A non-integer variable which is
being set by a paradoxical subreg is probably not a biv.
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 291d766..be458ce 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -963,6 +963,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
register rtx op0 = str_rtx;
rtx spec_target = target;
rtx spec_target_subreg = 0;
+ enum machine_mode int_mode;
#ifdef HAVE_extv
int extv_bitsize;
enum machine_mode extv_mode;
@@ -1168,10 +1169,19 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
NULL_RTX, 0);
}
- /* From here on we know the desired field is smaller than a word
- so we can assume it is an integer. So we can safely extract it as one
- size of integer, if necessary, and then truncate or extend
- to the size that is wanted. */
+ /* From here on we know the desired field is smaller than a word. */
+
+ /* Check if there is a correspondingly-sized integer field, so we can
+ safely extract it as one size of integer, if necessary; then
+ truncate or extend to the size that is wanted; then use SUBREGs or
+ convert_to_mode to get one of the modes we really wanted. */
+
+ int_mode = int_mode_for_mode (tmode);
+ if (int_mode == BLKmode)
+ int_mode = int_mode_for_mode (mode);
+ if (int_mode == BLKmode)
+ abort(); /* Should probably push op0 out to memory and then
+ do a load. */
/* 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. */
@@ -1326,15 +1336,15 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
else
{
delete_insns_since (last);
- target = extract_fixed_bit_field (tmode, op0, offset, bitsize,
+ target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
bitpos, target, 1, align);
}
}
else
extzv_loses:
#endif
- target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
- target, 1, align);
+ target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
+ bitpos, target, 1, align);
}
else
{
@@ -1462,15 +1472,15 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
else
{
delete_insns_since (last);
- target = extract_fixed_bit_field (tmode, op0, offset, bitsize,
+ target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
bitpos, target, 0, align);
}
}
else
extv_loses:
#endif
- target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
- target, 0, align);
+ target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
+ bitpos, target, 0, align);
}
if (target == spec_target)
return target;