aboutsummaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@gcc.gnu.org>2003-09-29 21:29:11 +0000
committerZack Weinberg <zack@gcc.gnu.org>2003-09-29 21:29:11 +0000
commitb409761a1f5f5363a16d46df667508440c8dfd4b (patch)
treebb342df38ab5769485ec71734c68bfcc6907976b /gcc/varasm.c
parentf820b0cf2cb6595ed42b16fd1615eb3aec0a6ada (diff)
downloadgcc-b409761a1f5f5363a16d46df667508440c8dfd4b.zip
gcc-b409761a1f5f5363a16d46df667508440c8dfd4b.tar.gz
gcc-b409761a1f5f5363a16d46df667508440c8dfd4b.tar.bz2
varasm.c (assemble_real): Use real_to_target directly...
* varasm.c (assemble_real): Use real_to_target directly, calculate the number of significant elements of the result array and write them out in a loop, instead of using a giant switch statement to pick the correct REAL_VALUE_TO_TARGET_* macro. From-SVN: r71917
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c97
1 files changed, 27 insertions, 70 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index e6d0189..47db821 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1890,77 +1890,34 @@ void
assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)
{
long data[4];
- long l;
- unsigned int nalign = min_align (align, 32);
-
- switch (BITS_PER_UNIT)
+ int i;
+ int bitsize, nelts, nunits, units_per;
+
+ /* This is hairy. We have a quantity of known bitsize. real_to_target
+ will put it into an array of *host* longs, 32 bits per element
+ (even if long is more than 32 bits). We need to determine the
+ number of array elements that are occupied (nelts) and the number
+ of *target* min-addressable units that will be occupied in the
+ object file (nunits). We can assume that BITS_PER_UNIT divides
+ the mode's bitsize evenly, but we can not assume that 32 does. */
+ bitsize = GET_MODE_BITSIZE (mode);
+ nunits = bitsize / BITS_PER_UNIT;
+ nelts = CEIL (bitsize, 32);
+ units_per = 32 / BITS_PER_UNIT;
+
+ real_to_target (data, &d, mode);
+
+ /* Put out the first word with the specified alignment. */
+ assemble_integer (GEN_INT (data[0]), MIN (nunits, units_per), align, 1);
+ nunits -= units_per;
+
+ /* Subsequent words need only 32-bit alignment. */
+ align = min_align (align, 32);
+
+ for (i = 1; i < nelts; i++)
{
- case 8:
- switch (mode)
- {
- case SFmode:
- REAL_VALUE_TO_TARGET_SINGLE (d, l);
- assemble_integer (GEN_INT (l), 4, align, 1);
- break;
- case DFmode:
- REAL_VALUE_TO_TARGET_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 4, align, 1);
- assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
- break;
- case XFmode:
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 4, align, 1);
- assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
- assemble_integer (GEN_INT (data[2]), 4, nalign, 1);
- break;
- case TFmode:
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 4, align, 1);
- assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
- assemble_integer (GEN_INT (data[2]), 4, nalign, 1);
- assemble_integer (GEN_INT (data[3]), 4, nalign, 1);
- break;
- default:
- abort ();
- }
- break;
-
- case 16:
- switch (mode)
- {
- case HFmode:
- REAL_VALUE_TO_TARGET_SINGLE (d, l);
- assemble_integer (GEN_INT (l), 2, align, 1);
- break;
- case TQFmode:
- REAL_VALUE_TO_TARGET_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 2, align, 1);
- assemble_integer (GEN_INT (data[1]), 1, nalign, 1);
- break;
- default:
- abort ();
- }
- break;
-
- case 32:
- switch (mode)
- {
- case QFmode:
- REAL_VALUE_TO_TARGET_SINGLE (d, l);
- assemble_integer (GEN_INT (l), 1, align, 1);
- break;
- case HFmode:
- REAL_VALUE_TO_TARGET_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 1, align, 1);
- assemble_integer (GEN_INT (data[1]), 1, nalign, 1);
- break;
- default:
- abort ();
- }
- break;
-
- default:
- abort ();
+ assemble_integer (GEN_INT (data[i]), MIN (nunits, units_per), align, 1);
+ nunits -= units_per;
}
}