NetBSD Problem Report #45857

From  Thu Jan 19 04:58:07 2012
Return-Path: <>
Received: from ( [])
	by (Postfix) with ESMTP id DCA3963BF06
	for <>; Thu, 19 Jan 2012 04:58:06 +0000 (UTC)
Message-Id: <>
Date: Thu, 19 Jan 2012 04:58:05 +0000 (UTC)
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:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 19 05:00:01 +0000 2012
>Closed-Date:    Mon Mar 14 05:45:40 +0000 2022
>Last-Modified:  Mon Mar 14 05:45:40 +0000 2022
>Originator:     Jake Hamby
>Release:        5.99.60
NetBSD amiga1 5.99.60 NetBSD 5.99.60 (WARP3000) #0: Sun Jan 15 02:23:14 PST 2012 amiga
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/ 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 if they were compiled with "-m68040" so that its math routines don't include references to the undefined __fixxfsi function.
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;

Index: external/gpl3/gcc/dist/gcc/config/m68k/
RCS file: /cvsroot/src/external/gpl3/gcc/dist/gcc/config/m68k/,v
retrieving revision 1.2
diff -u -r1.2
--- external/gpl3/gcc/dist/gcc/config/m68k/	21 Jun 2011 02:41:37 -0000	1.2
+++ external/gpl3/gcc/dist/gcc/config/m68k/	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"



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

State-Changed-From-To: open->closed
State-Changed-When: Mon, 14 Mar 2022 05:45:40 +0000
not sure when, but this has been fixed for a little while (libgcc* has __fixxfsi.)


NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: gnats-precook-prs,v 1.4 2018/12/21 14:20:20 maya Exp $
$NetBSD:,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.