Ticket #43 (closed defect: fixed)

Opened 3 years ago

Last modified 3 years ago

Bug in the AMS float support of GCC on 64-bit platforms...

Reported by: debrouxl Owned by:
Priority: critical Milestone: Version 1.00
Component: project Version: 0.96
Keywords: Cc: kevin.kofler@…, cemeyer@…

Description

I've mentioned this earlier this morning on #GCC4TI.

Yesterday, when compiling an application that uses floats on my 64-bit SimplyMEPIS 8 (Debian Lenny), the assembler spat warnings about truncated integers.

-save-temps revealed that the offending .s indeed contains values that cannot fit into a .long, such as

	.word	16384
	.long	1073741824
	.long	4611686018427387904

That screams like a 64-bit compatibility problem...

Hmm, what happens if I recompile gcc and binutils with -m32 ?
=> the problem disappears, as expected (if it occurred on 32-bit platforms, such a problem would have been detected and fixed a long time ago).

OK, so where is the offending code ? It must be the TIGCC patch, since upstream GCC doesn't support AMS floats.
A little digging later, I came across the following hunk of gcc/varasm.c:

@@ -2280,7 +2360,16 @@ void assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)
 {
-  long data[4];
+  long data[3];
+  unsigned int nalign = min_align (align, 16);
+
+  /* This is how to output a SMAP BCD real constant. */
+  REAL_VALUE_TO_TARGET_SMAP_BCD (d, data);
+  assemble_integer (GEN_INT (data[0]), 2, align, 1);
+  assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
+  assemble_integer (GEN_INT (data[2]), 4, nalign, 1);
+
+#if 0
   int i;
   int bitsize, nelts, nunits, units_per;

What if I try to clamp the values, and recompile the compiler as a 64-bit executable from a fresh source tree:

@@ -2280,7 +2360,16 @@ void assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)
 {
-  long data[4];
+  long data[3];
+  unsigned int nalign = min_align (align, 16);
+
+  /* This is how to output a SMAP BCD real constant. */
+  REAL_VALUE_TO_TARGET_SMAP_BCD (d, data);
+  assemble_integer (GEN_INT (data[0] & 0xFFFFUL), 2, align, 1);
+  assemble_integer (GEN_INT (data[1] & 0xFFFFFFFFUL), 4, nalign, 1);
+  assemble_integer (GEN_INT (data[2] & 0xFFFFFFFFUL), 4, nalign, 1);
+
+#if 0
   int i;
   int bitsize, nelts, nunits, units_per;

=> the problem disappears.

Revert this change and recompile => the problem reappears.

Re-apply this change => the problem disappears.

I'm not sure my change is the best possible fix, which is why I'm opening this bug.
The "Float Test" and "Sort Floats" examples can be used as reduced testcases.

Change History

comment:1 Changed 3 years ago by debrouxl

  • Status changed from new to closed
  • Resolution set to fixed

Committed the change described in this ticket as r1325.

Note: See TracTickets for help on using tickets.