Subject: using _SOFT_FLOAT and MKSOFTFLOAT=yes with
To: None <>
From: M L Riechers Mlr <>
List: tech-toolchain
Date: 08/10/2002 02:47:54
Well, I'm stumped.

I've got a mac 7500 (upgraded to a G3 powerpc processor), and have
successfully (I believe) upgraded from NetBSD 1.5v:
NetBSD 1.5V (EASTERN-1V.backside) #0: Tue Sep 11 23:08:22 EDT 2001
to NetBSD 1.6_BETA4:
NetBSD 1.6_BETA4 (EASTERN-1.6Beta4.backside) #0: Tue Jul 23 23:27:54 EDT 2002
from ftp sources 20 July 2002.  For the first time I used the Build
mechanism as (quasi) cross, and all eventually worked out.  Thanks
indeed to the new toolchain, and you all who made it.

So far so good.  But what I'm really trying to do is port to (for
right now) an mpc860 powerpc processor, which _is_ standard powerpc,
except that it doesn't have a floating point unit (nor BATS or segment
regs, but that's another story).  So, the mac compiler should be able
to compile for the 860 by passing "-mcpu=823" to the compiler.  But,
there are other issues, such as implementing the soft float library,
and passing float values in GP registers, instead of FP registers.

I managed to get the "860" running under 1.5v by compiling a kernel
and then a distribution (first adding #define TARGET_CPU_DEFAULT "821"
just before #include "rs6000/netbsd.h" in
src/gnu/usr.bin/egcs/arch/powerpc/tm.h) using the macppc native
compiler and doing:

nohup sh -c date; export MACHINE=mpc823; export NOGCCERROR=1; \
export SOFTFLOAT=1; export COPTS=" -mcpu=821 -DSOFTFLOAT"; \
export DESTDIR=/mnt; export LOCALTIME=US/Eastern; make build; date

and then chroot'ing to /mnt and re-running almost the same script:

nohup sh -c date; export MACHINE=mpc823; export NOGCCERROR=1; \
export SOFTFLOAT=1; export COPTS=" -mcpu=821 -DSOFTFLOAT"; \
export DESTDIR=/; export LOCALTIME=US/Eastern; make build; date

which would presumably use the 860's tools and libraries.  I had a
devil of a time with awk, however.  It wouldn't work correctly unless
I statically linked it -- I believe its difficulties were with
floating point.  ( I hard-hacked /usr/include/stdarg.h to get top to
compute correctly -- but that was before I found Tsubai Masanari's, I
believe, #ifdef _SOFT_FLOAT change of 2001/05/31.)  I don't believe I
had the 1.5V version properly passing float values to the shared libs,
and I don't know why.  So I thought it profitable to try 1.6.

I see that the walnut port traps floating point instructions to the
kernel for emulation.  For various reasons, I'd rather not do that
right now, and instead would prefer to build a compiler that always
DTRT to compile in floating point emulation, and to pass the FP values
correctly in GP regs.

What I've done so far is to heavy-handedly hack parts of the
distribution (yes, I know, it's not even close to Right(tm), but for
now, I just want some results) to get gcc to do -msoft-float and emit
_SOFT_FLOAT to the pre-processor _all_ the time.  (The build ignores
the contents of src/gnu/usr.bin/gcc/arch/powerpc/tm.h for the cross
compiler.) (_SOFT_FLOAT is necessary to convince powerpc include file
/usr/include/powerpc/stdarg.h to pass float variables in the GP regs,
and to shut down some powerpc float assist routines which try to use
floating point regs in assembly statements.  gas makes a fuss about
your using FP regs if you tell it it's dealing with an mpc core -- no
hardware float available.  Very noisy.)  My hack is this:

--- ./src/tools//toolchain/Makefile.ori	Thu Feb 28 07:14:30 2002
+++ ./src/tools//toolchain/Makefile	Sun Jul 28 07:04:11 2002
@@ -7,7 +7,7 @@
 FIND_ARGS=	\! \( -type d -name sim -prune \)
 CONFIGURE_ENV=	LANGUAGES="c c++ objc f77"
-CONFIGURE_ARGS=	--target=${MACHINE_GNU_PLATFORM} --disable-nls \
+CONFIGURE_ARGS=	--target=${MACHINE_GNU_PLATFORM} --with-cpu=823 --disable-nls \
--- ./src/gnu/dist/toolchain/gcc/configure.ori	Tue May 21 06:42:57 2002
+++ ./src/gnu/dist/toolchain/gcc/configure	Sun Jul 28 07:20:54 2002
@@ -5091,6 +5091,32 @@
 		tmake_file="${tmake_file} rs6000/t-rs6000"
 		xm_file="rs6000/xm-sysv4.h xm-netbsd.h"
+		case "x$with_cpu" in
+			x)
+				;;
+			xcommon | xpower | xpower2 | xpowerpc | xrios \
+			  | xrios1 | xrios2 | xrsc | xrsc1 \
+			  | x601 | x602 | x603 | x603e | x604 | x604e | x620 \
+			  | xec603e | x740 | x750 | x401 \
+			  | x403 | x505 | x801 | x821 | x823 | x860)
+				target_cpu_default2="\"$with_cpu\""
+				echo "target_cpu_default2 is $target_cpu_default2"
+				;;
+			xyes | xno)
+				echo "--with-cpu must be passed a value" 1>&2
+				exit 1
+				;;
+			*)
+				if test x$pass2done = xyes
+				then
+					echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2
+					exit 1
+				fi
+				;;
+		esac
 		tmake_file="${tmake_file} rs6000/t-rs6000 rs6000/t-openbsd"

--- ./src/	Sat Jul 13 09:37:32 2002
+++ ./src/	Sun Jul 28 17:23:14 2002
@@ -39,7 +39,7 @@
-		bebox|mvmeppc|prep|sandpoint|walnut|*ppc)
+		bebox|mvmeppc|prep|sandpoint|walnut|mpc823|*ppc)
--- ./src/gnu/dist/toolchain/gcc/config/rs6000/netbsd.h.ori	Thu Dec 20 06:46:43 2001
+++ ./src/gnu/dist/toolchain/gcc/config/rs6000/netbsd.h	Sun Jul 28 21:10:28 2002
@@ -68,6 +68,7 @@
 #undef CPP_SPEC
 #define CPP_SPEC "\
 %{posix:-D_POSIX_SOURCE} \
 %{msoft-float:-D_SOFT_FLOAT} \
 %{mcall-sysv: -D_CALL_SYSV} %{mcall-aix: -D_CALL_AIX} %{!mcall-sysv: %{!mcall-aix: -D_CALL_SYSV}}"
--- src/lib/libc/arch/powerpc/softfloat/softfloat.h.ori	Tue May 14 06:52:13 2002
+++ src/lib/libc/arch/powerpc/softfloat/softfloat.h	Thu May 30 03:48:00 2002
@@ -1,4 +1,4 @@
-/*	$NetBSD: softfloat.h,v 1.3 2002/05/12 13:12:46 bjh21 Exp $	*/
+/*	$NetBSD: softfloat.h,v 1.4 2002/05/29 15:58:03 eeh Exp $	*/
 /* This is a derivative work. */
@@ -170,7 +170,9 @@
 flag float32_eq_signaling( float32, float32 );
 flag float32_le_quiet( float32, float32 );
 flag float32_lt_quiet( float32, float32 );
 flag float32_is_signaling_nan( float32 );
@@ -208,7 +210,9 @@
 flag float64_eq_signaling( float64, float64 );
 flag float64_le_quiet( float64, float64 );
 flag float64_lt_quiet( float64, float64 );
 flag float64_is_signaling_nan( float64 );
 #ifdef FLOATX80

Now, I make the thing this way:

nohup sh -c 'date; export NOGCCERROR=1; \ 
export DESTDIR=/usr/local/src/dest-for-mpc823; \
export MKSOFTFLOAT=yes; \
export LOCALTIME=US/Eastern; \
./ -m mpc823 \
-R /usr/local/src/tar_files-1.6beta4-release-for-mpc823 ; \
date' & 

(Why mpc823 all over the place?  Because the 860 is a way-point -- the
823's my final goal. But the core processor's the same 860 => 823 --
it makes no difference to the compiler.)

Things go merrily along -- tools are built, we're into the build
proper, libgcc is built, gcc is built, groff is built -- not even the
NOGCCERROR=1 is really necessary -- until it comes time to link gzip.
Then we get:

/usr/local/src/dest-for-mpc823/usr/lib/libc.a(softfloat.o): In function `__divsf3':
softfloat.o(.text+0x1908): multiple definition of `__divsf3'
/usr/local/src/dest-for-mpc823/usr/lib/libgcc.a(dp-bit.o)(.text+0x6a8): first defined here
/usr/local/src/src/tools/obj.mpc823/tools.NetBSD-1.6_BETA4-powerpc/powerpc--netbsd/bin/ld: Warnin
g: size of symbol `__divsf3' changed from 356 to 472 in softfloat.o

and similarly, abbreviated,

.../libc.a(softfloat.o): In function `__divsf3':
.../libc.a(softfloat.o): In function `__fixsfsi':
.../libc.a(softfloat.o): In function `__subsf3':
.../libc.a(softfloat.o): In function `__floatsidf':
.../libc.a(softfloat.o): In function `__extendsfdf2':
.../libc.a(softfloat.o): In function `__adddf3':
.../libc.a(softfloat.o): In function `__fixdfsi':
.../libc.a(softfloat.o): In function `__floatsisf':
.../libc.a(softfloat.o): In function `__divdf3':
.../libc.a(softfloat.o): In function `__muldf3':
.../libc.a(softfloat.o): In function `__truncdfsf2':
.../libc.a(softfloat.o): In function `__mulsf3':
.../libc.a(softfloat.o): In function `__subdf3':
.../libc.a(softfloat.o): In function `__addsf3':

whereupon, the whole parade stops.

So, both bits32/softfloat.c and gcc are supplying routines to support
these functions.  Why, and which one is preferable?

The change between 1.5v and 1.6 happened because of (perhaps the
difference between gcc 2.92(?) and 2.95.3?) 
src/tools/toolchain/obj.mpc823/build/gcc/Makefile that says, quote:

dp-bit.c: $(srcdir)/config/fp-bit.c
        cat $(srcdir)/config/fp-bit.c > dp-bit.c

fp-bit.c: $(srcdir)/config/fp-bit.c
        echo '#define FLOAT' > fp-bit.c
        cat $(srcdir)/config/fp-bit.c >> fp-bit.c

# Build the libraries for both hard and soft floating point

MULTILIB_OPTIONS = msoft-float

which produces (I think) with a host of other stuff, (but surely I'm
mistaken, for dp-bit.c doesn't look dead similar to fp-bit with the
dp-bit without ..... nooooo, it can't, I am mistaken)

printf '#define FLOAT\n#include <fp-bit.c>\n' >dp-bit.c

just before making libgcc.  This apparently makes the libgcc soft
floating point support routines, which 1.5v didn't do.

Other than the stuff in src/lib/libc/arch, and MKSOFTFLOAT, I can't
see where or what is directing this soft float stuff.  Nothing seems
to be in any of the src/sys/arch's directing this stuff.  In fact, the
gcc stuff seems so general that I'm puzzled as to why the non-hardware
float and semi-non-hardware float architectures work.

So, am I going about this all wrong?  What should I do?  Would it help
to do something very similar to what I did last time? (I suspect it
would not -- i.e. is my problem only in the build system, or would it
follow me into the native system?)  Should I comment out these
routines in softfloat.c with #ifdef SOFTFLOAT_FOR_GCC ?  Suppress
somehow the libgcc routines?  Would 1.6-current and gcc 3.+ be a
better bet?  Are my hacks really lousy, and there's a better way? But,
am I going about this all wrong?

Thanks in advance,