NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
port-m68k/45857: undefined ref to __fixxfsi in code compiled with -m68040
>Number: 45857
>Category: port-m68k
>Synopsis: undefined ref to __fixxfsi in code compiled with -m68040
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-m68k-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jan 19 05:00: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@localhost:/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"
Home |
Main Index |
Thread Index |
Old Index