NetBSD Problem Report #45857

From www@NetBSD.org  Thu Jan 19 04:58:07 2012
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by www.NetBSD.org (Postfix) with ESMTP id DCA3963BF06
	for <gnats-bugs@gnats.NetBSD.org>; Thu, 19 Jan 2012 04:58:06 +0000 (UTC)
Message-Id: <20120119045805.3DFD063B9DD@www.NetBSD.org>
Date: Thu, 19 Jan 2012 04:58:05 +0000 (UTC)
From: jake.hamby@gmail.com
Reply-To: jake.hamby@gmail.com
To: gnats-bugs@NetBSD.org
Subject: undefined ref to __fixxfsi in code compiled with -m68040
X-Send-Pr-Version: www-1.0

>Number:         45857
>Category:       port-m68k
>Synopsis:       undefined ref to __fixxfsi in code compiled with -m68040
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    mrg
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 19 05:00:01 +0000 2012
>Last-Modified:  Fri Oct 05 05:47:01 +0000 2012
>Originator:     Jake Hamby
>Release:        5.99.60
>Organization:
Google
>Environment:
NetBSD amiga1 5.99.60 NetBSD 5.99.60 (WARP3000) #0: Sun Jan 15 02:23:14 PST 2012  jhamby@fast1.alpha1bbs.org:/home/jhamby/NetBSD-current/obj/sys/arch/amiga/compile/WARP3000 amiga
>Description:
GCC 4.5.3 on m68k is generating undefined references to __fixxfsi for any code that converts long doubles to int (or short or char) when the "-m68040" flag is set (but not -m68060). This is a soft-float function that isn't defined in libgcc.a.

What's happening is that gcc/config/m68k/m68k.md generates different code for truncating floats to ints when TUNE_68040 is set because the M68040 must trap to the kernel to emulate the fintrz instruction that would otherwise be generated. This works for doubles, but not for long double types, and for some reason GCC is emitting code to call a soft-float routine that isn't included in libgcc for those cases.

I've attached a patch that fixes the problem by generalizing the fix_truncdfsi2, fix_truncdfhi2, and fix_truncdfqi2 instructions for "TARGET_68881 && TUNE_68040" to work for any of the floating point types. I haven't tested the code thoroughly yet, so I'll add to the PR if I discover any problems with the patch. It's a fairly straightforward change to use the same template that other platforms, e.g. i386, use for the same instruction patterns.

It's necessary to rebuild libgcc.a and libgcc_s.so.1 if they were compiled with "-m68040" so that its math routines don't include references to the undefined __fixxfsi function.
>How-To-Repeat:
This test program will fail to link with an "undefined reference to `__fixxfsi'" error when compiled with GCC 4.5.3 and "-m68040". It links and runs successfully when GCC and libgcc are recompiled with the attached patch.

#include <stdio.h>

long double gettestvalue() {
        int i;
        long double test = 1.0, test2 = 1.0;
        for (i = 0; i < 10; i++) {
                test2 /= 2;
                test = test + test2;
        }
        return test;
}

int main() {
        long double testval = gettestvalue();
        printf("testval is %Lg\n", testval);
        printf("testval as char is %d\n", (char) testval);
        printf("testval as short is %d\n", (short) testval);
        printf("testval as int is %d\n", (int) testval);
        printf("testval as long long is %lld\n", (long long) testval);
        return 0;
}

>Fix:
Index: external/gpl3/gcc/dist/gcc/config/m68k/m68k.md
===================================================================
RCS file: /cvsroot/src/external/gpl3/gcc/dist/gcc/config/m68k/m68k.md,v
retrieving revision 1.2
diff -u -r1.2 m68k.md
--- external/gpl3/gcc/dist/gcc/config/m68k/m68k.md	21 Jun 2011 02:41:37 -0000	1.2
+++ external/gpl3/gcc/dist/gcc/config/m68k/m68k.md	19 Jan 2012 04:24:17 -0000
@@ -2115,9 +2115,9 @@
 ;; into the kernel to emulate fintrz.  They should also be faster
 ;; than calling the subroutines fixsfsi or fixdfsi.

-(define_insn "fix_truncdfsi2"
+(define_insn "fix_trunc<mode>si2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
-	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
+	(fix:SI (match_operand:FP 1 "register_operand" "f")))
    (clobber (match_scratch:SI 2 "=d"))
    (clobber (match_scratch:SI 3 "=d"))]
   "TARGET_68881 && TUNE_68040"
@@ -2126,9 +2126,9 @@
   return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.l %1,%0\;fmovem%.l %2,%!";
 })

-(define_insn "fix_truncdfhi2"
+(define_insn "fix_trunc<mode>hi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
-	(fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
+	(fix:HI (match_operand:FP 1 "register_operand" "f")))
    (clobber (match_scratch:SI 2 "=d"))
    (clobber (match_scratch:SI 3 "=d"))]
   "TARGET_68881 && TUNE_68040"
@@ -2137,9 +2137,9 @@
   return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.w %1,%0\;fmovem%.l %2,%!";
 })

-(define_insn "fix_truncdfqi2"
+(define_insn "fix_trunc<mode>qi2"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
-	(fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
+	(fix:QI (match_operand:FP 1 "register_operand" "f")))
    (clobber (match_scratch:SI 2 "=d"))
    (clobber (match_scratch:SI 3 "=d"))]
   "TARGET_68881 && TUNE_68040"

>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: port-m68k-maintainer->mrg
Responsible-Changed-By: mrg@NetBSD.org
Responsible-Changed-When: Fri, 05 Oct 2012 05:47:01 +0000
Responsible-Changed-Why:
i'll see about merging this change.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.