Query on status of cross-builds
Marius Strobl
marius at alchemy.franken.de
Wed Jul 7 13:05:45 PDT 2004
On Fri, Jul 02, 2004 at 03:50:17PM -0700, Marcel Moolenaar wrote:
> On Sat, Jul 03, 2004 at 12:19:36AM +0300, Ruslan Ermilov wrote:
> > >
> > > No. It's a compiler bug on sparc64. I think the old binutils just
> > > didn't complain about the invalid instruction. I compared the
> > > output of the native cc and the cross cc and they are different.
> > > Not much, but fataly so.
> > >
> > Yes, I produced that diff as well (by using -save-temps).
> > Unfortunately, I don't know sparc64 assembler at all...
>
> [context: the faulty instruction is the fstox in the following snippet]
>
> fmuls %f8, %f9, %f8
> fstox %f8, %f7
> st %f8, [%fp+2031]
>
> As far as I can tell, the fstox is faulty because the target
> FP register is a double extended FP, which therefore has to be
> an even numbered FP register. The native cc uses %f12, while
> the cross cc uses %f7.
>
> Simply replacing %f7 with %f6 or %f8 resolves the problem. Note
> that %f8 should have been the register, because it's used by
> the subsequent st instruction.
>
> I have no idea why a cross cc would trigger this. Maybe there's
> a flags field with more than 32 flags and defined as long. On 64-bit
> machines this works out well, on 32-bit machines this breaks.
> I dunno...
>
I hit this bug also with a native compilation on sparc64 trying to
build nmap. The patch below fixes both the cross-buildworlds and
the nmap build. It's taken from the GCC gcc-3_3-branch branch
(sparc.h revision 1.215.4.4) so it can be committed to the FSF
branch in FreeBSD. It's also part of GCC 3.4 and 3.4.1.
I have no idea why GNU tar trigged the bug only when cross building
for sparc64.
Index: sparc.h
===================================================================
RCS file: /usr/data/bsd/cvs/fbsd/src/contrib/gcc/config/sparc/sparc.h,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 sparc.h
--- sparc.h 11 Jul 2003 03:40:53 -0000 1.1.1.6
+++ sparc.h 7 Jul 2004 13:02:48 -0000
@@ -1233,6 +1233,20 @@
{-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */ \
{-1, -1, -1, 0x3f}} /* ALL_REGS */
+/* Defines invalid mode changes. Borrowed from pa64-regs.h.
+
+ SImode loads to floating-point registers are not zero-extended.
+ The definition for LOAD_EXTEND_OP specifies that integer loads
+ narrower than BITS_PER_WORD will be zero-extended. As a result,
+ we inhibit changes from SImode unless they are to a mode that is
+ identical in size. */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (TARGET_ARCH64 \
+ && (FROM) == SImode \
+ && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
+
/* The same information, inverted:
Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
More information about the freebsd-current
mailing list