summaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.c
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2001-11-29 18:12:37 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2001-11-29 18:12:37 +0000
commitdb6bf7a6b0a2bf4818ac1eb31004b568e2c58eaf (patch)
treebef4d46a4315839be469b124f09a3ba4c90da806 /gcc/emit-rtl.c
parent4605907b1ba3ea30e5183ed2956b394b6ea4d4e7 (diff)
downloadgcc-db6bf7a6b0a2bf4818ac1eb31004b568e2c58eaf.tar.gz
* emit-rtl.c (gen_lowpart_common): Fix conversion of
REAL_VALUE_TYPEs to an array of target integers. Fix extraction of low part of those arrays for 32bit and 64bit hosts. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@47446 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r--gcc/emit-rtl.c52
1 files changed, 18 insertions, 34 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 5e344b5d973..f3fda29e6dc 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -1027,19 +1027,25 @@ gen_lowpart_common (mode, x)
long i[4]; /* Only the low 32 bits of each 'long' are used. */
int endian = WORDS_BIG_ENDIAN ? 1 : 0;
+ /* Convert 'r' into an array of four 32-bit words in target word
+ order. */
REAL_VALUE_FROM_CONST_DOUBLE (r, x);
switch (GET_MODE_BITSIZE (GET_MODE (x)))
{
case 32:
- REAL_VALUE_TO_TARGET_SINGLE (r, i[endian]);
- i[1 - endian] = 0;
- break;
+ REAL_VALUE_TO_TARGET_SINGLE (r, i[3 * endian]);
+ i[1] = 0;
+ i[2] = 0;
+ i[3 - 3 * endian] = 0;
+ break;
case 64:
- REAL_VALUE_TO_TARGET_DOUBLE (r, i);
- break;
+ REAL_VALUE_TO_TARGET_DOUBLE (r, i + 2 * endian);
+ i[2 - 2 * endian] = 0;
+ i[3 - 2 * endian] = 0;
+ break;
case 96:
REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, i + endian);
- i[3-3*endian] = 0;
+ i[3 - 3 * endian] = 0;
break;
case 128:
REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, i);
@@ -1047,39 +1053,17 @@ gen_lowpart_common (mode, x)
default:
abort ();
}
-
/* Now, pack the 32-bit elements of the array into a CONST_DOUBLE
and return it. */
#if HOST_BITS_PER_WIDE_INT == 32
- return immed_double_const (i[endian], i[1 - endian], mode);
+ return immed_double_const (i[3 * endian], i[1 + endian], mode);
#else
- {
- int c;
-
- if (HOST_BITS_PER_WIDE_INT != 64)
- abort ();
-
- for (c = 0; c < 4; c++)
- i[c] &= ~ (0L);
+ if (HOST_BITS_PER_WIDE_INT != 64)
+ abort ();
- switch (GET_MODE_BITSIZE (GET_MODE (x)))
- {
- case 32:
- case 64:
- return immed_double_const (((unsigned long) i[endian]) |
- (((HOST_WIDE_INT) i[1-endian]) << 32),
- 0, mode);
- case 96:
- case 128:
- return immed_double_const (((unsigned long) i[endian*3]) |
- (((HOST_WIDE_INT) i[1+endian]) << 32),
- ((unsigned long) i[2-endian]) |
- (((HOST_WIDE_INT) i[3-endian*3]) << 32),
- mode);
- default:
- abort ();
- }
- }
+ return immed_double_const (i[3 * endian] | (i[1 + endian] << 32),
+ i[2 - endian] | (i [3 - 3 * endian] << 32),
+ mode);
#endif
}
#endif /* ifndef REAL_ARITHMETIC */