--- libc-sparc-5.3.12.orig/libc/ChangeLog
+++ libc-sparc-5.3.12/libc/ChangeLog
@@ -1,3 +1,7 @@
+Thu May  9 23:02:39 1996  Miguel de Icaza  <miguel@luthien.nuclecu.unam.mx>
+
+	* sysdeps/sparc/udiv_qrnnd.S: Made Sparc PIC aware.
+
 Wed Apr 24 22:05:14 1996  H.J. Lu (hjl@gnu.ai.mit.edu)
 
 	* version 5.3.12 is released.
--- libc-sparc-5.3.12.orig/libc/Makeconfig
+++ libc-sparc-5.3.12/libc/Makeconfig
@@ -136,7 +136,10 @@
 TARGET_SBIN_DIR=$(TARGET_ROOTDIR)sbin
 TARGET_SO_DIR=$(TARGET_ROOTDIR)lib
 TARGET_LIBM_SO_DIR=$(TARGET_ROOTDIR)lib
-CROSS_ROOTDIR=$(HOST_ROOTDIR)
+# [Debian] CROSS_ROOTDIR should points to libc6 tools as well because both
+#          are in the same (ELF) format.
+#CROSS_ROOTDIR=$(HOST_ROOTDIR)
+CROSS_ROOTDIR=/usr
 TARGET_LIBEXTRA_DIR=$(TARGET_ROOTDIR)usr/lib
 
 TARGET_ELF_SO_DIR=$(TARGET_ROOTDIR)lib
@@ -320,7 +323,7 @@
 
 
 XCFLAGS = -D_GNU_SOURCE -DSTDC_HEADERS -DUSG -DDIRENT -DSYSV \
-	-DUSE_BSD_REGEX -D_LIBC \
+	-DUSE_BSD_REGEX -D_LIBC -D_REENTRANT \
 	-DINTERNAL_LINUX_C_LIB # -D__USE_BSD_SIGNAL
 
 ifeq ($(ELF),)
@@ -337,7 +340,10 @@
 # You can put your system header files in somewhere else. We
 # assume they are in ../include.
 SYSTEM_INC_DIR=$(TOPDIR)/../include
+# [Debian] kernel headers required to build the libc
+KERNEL_INC_DIR=$(TOPDIR)/../kernel-include
 SYSTEM_INC_CFLAGS:=-nostdinc -I$(SYSTEM_INC_DIR) \
+	-I$(KERNEL_INC_DIR) \
 	-I`$(REALCC) -print-libgcc-file-name | sed -e 's/libgcc.a/include/'`
 
 BASE_CFLAGS= $(INC_CFLAGS) \
@@ -358,8 +364,8 @@
 OPT_CFLAGS= -O1 -funroll-loops
 endif
 ifeq ($(PIC_OPT_CFLAGS),)
-PIC_OPT_CFLAGS= -fPIC -O1 -funroll-loops -fomit-frame-pointer
-PIC_OPT_CFLAGS= -fPIC -O6 -funroll-loops -fomit-frame-pointer
+PIC_OPT_CFLAGS= -D__PIC__ -fPIC -O1 -funroll-loops -fomit-frame-pointer
+PIC_OPT_CFLAGS= -D__PIC__ -fPIC -O6 -funroll-loops -fomit-frame-pointer
 endif
 ifeq ($(DEBUG_OPT_CFLAGS),)
 DEBUG_OPT_CFLAGS=-O -g # -mreg-alloc=d
@@ -394,6 +400,10 @@
 
 ifeq ($(TARGET__MACHINE),i386-linux)
 CANONICAL_TARGET_MACHINE=ix86-linux
+endif
+
+ifeq ($(TARGET__MACHINE),sparc-linux)
+CANONICAL_TARGET_MACHINE=sparc-linux
 endif
 
 ifeq ($(TARGET__MACHINE),i486-linux)
--- libc-sparc-5.3.12.orig/libc/Makefile
+++ libc-sparc-5.3.12/libc/Makefile
@@ -53,6 +53,9 @@
 
 all: lib
 
+doone:
+	set -e; $(MAKE) -C $(THEDIR) lib
+
 lib:
 	set -e; for i in $(DIRS); do \
 		echo making $@ in $$i; \
--- libc-sparc-5.3.12.orig/libc/Makerules
+++ libc-sparc-5.3.12/libc/Makerules
@@ -5,7 +5,7 @@
 	$(CC) $(PIC_CFLAGS) -c $<
 
 .S.o:
-	$(CC) $(PIC_CFLAGS) -c $<
+	$(CC) $(PIC_CFLAGS) -D__ASSEMBLY__ -c $<
 
 .c.o:
 ifeq ($(SHARED),true)
@@ -54,7 +54,7 @@
 endif
 
 .S.s:
-	$(CC) $(PIC_CFLAGS) -E $< -o $*.s
+	$(CC) $(PIC_CFLAGS) -D__ASSEMBLY__ -E $< -o $*.s
 
 .c.s:
 ifeq ($(SHARED),true)
@@ -139,7 +139,7 @@
 
 $(STATIC_DIR)/$(SUBDIR)/%.o $(SHARED_DIR)/$(SUBDIR)/%.o \
 	$(DEBUG_DIR)/$(SUBDIR)/%.o $(PROFILE_DIR)/$(SUBDIR)/%.o: %.S
-	$(CC) $(CFLAGS) -E $< -o $*.s
+	$(CC) $(CFLAGS) -D__ASSEMBLY__ -E $< -o $*.s
 	$(JUMPAS)as -o $(SHARED_DIR)/$(SUBDIR)/$*.o  $*.s
 	$(AS) -o $(STATIC_DIR)/$(SUBDIR)/$*.o $*.s
 ifeq ($(DEBUG),true)
@@ -153,11 +153,11 @@
 else
 
 $(SHARED_DIR)/$(SUBDIR)/%.o: %.S
-	$(CC) $(PIC_CFLAGS) -c $< -o $@
+	$(CC) $(PIC_CFLAGS) -D__ASSEMBLY__ -c $< -o $@
 
 $(STATIC_DIR)/$(SUBDIR)/%.o \
 	$(DEBUG_DIR)/$(SUBDIR)/%.o $(PROFILE_DIR)/$(SUBDIR)/%.o: %.S
-	$(CC) $(CFLAGS) -c $< -o $@
+	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
 ifeq ($(DEBUG),true)
 	cp $(STATIC_DIR)/$(SUBDIR)/$*.o $(DEBUG_DIR)/$(SUBDIR)
 endif
@@ -188,16 +188,16 @@
 else
 
 $(SHARED_DIR)/$(SUBDIR)/%.o $(SHARED_DIR)/%.o: %.S
-	$(CC) $(PIC_CFLAGS) -c $< -o $@
+	$(CC) $(PIC_CFLAGS) -D__ASSEMBLY__ -c $< -o $@
 
 $(STATIC_DIR)/$(SUBDIR)/%.o $(STATIC_DIR)/%.o: %.S
-	$(CC) $(CFLAGS) -c $< -o $@
+	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
 
 $(PROFILE_DIR)/$(SUBDIR)/%.o $(PROFILE_DIR)/%.o: %.S
-	$(CC) $(CFLAGS) -c $< -o $@
+	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
 
 $(DEBUG_DIR)/$(SUBDIR)/%.o: %.S
-	$(CC) $(CFLAGS) -c $< -o $@
+	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
 
 $(SHARED_DIR)/$(SUBDIR)/%.o: %.c
 	$(CC) $(PIC_CFLAGS) -c $< -o $@
@@ -232,5 +232,5 @@
 	$(CC) $(CHECKER_CFLAGS) -c $< -o $@
 
 $(CHECKER_DIR)/$(SUBDIR)/%.o $(CHECKER_DIR)/%.o: %.S
-	$(CC) $(CHECKER_CFLAGS) $(CHECKER_ASFLAGS) -c $< -o $@
+	$(CC) $(CHECKER_CFLAGS) $(CHECKER_ASFLAGS) -D__ASSEMBLY__ -c $< -o $@
 endif
--- libc-sparc-5.3.12.orig/libc/configure
+++ libc-sparc-5.3.12/libc/configure
@@ -63,7 +63,7 @@
     TMP=m;
     ;;
   esac
-  TARGET_ARCH=`response "Build 386, 486, 586 or m68k library code 3/4/5/m" "${TMP}"`
+  TARGET_ARCH=`response "Build 386, 486, 586, SPARC or m68k library code 3/4/5/s/m" "${TMP}"`
 
   case i${TARGET_ARCH} in
   i5)
@@ -86,6 +86,11 @@
     TARGET_ARCH_x86=;
     TARGET_ARCH=m68k;
     ;;
+  is)
+    TARGET_MACHINE=sparc-linux
+    TARGET_ARCH_x86=;
+    TARGET_ARCH=sparc;
+    ;;
   *)
     echo Unknown arch: \"${TARGET_ARCH}\".
     exit 1
@@ -340,6 +345,10 @@
       *68*)
 	TARGET_ARCH_x86=
 	TARGET_ARCH=m68k
+	;;
+      *sparc*)
+	TARGET_ARCH_x86=
+	TARGET_ARCH=sparc
 	;;
       *)
 	echo Oops: Unknown target machine "$TARGET_MACHINE".
--- libc-sparc-5.3.12.orig/libc/elf/crt/config/svr4.h
+++ libc-sparc-5.3.12/libc/elf/crt/config/svr4.h
@@ -1,7 +1,7 @@
-/* svr4.h  --  operating system specific defines to be used when
-   targeting GCC for some generic System V Release 4 system.
-   Copyright (C) 1991, 1994 Free Software Foundation, Inc.
-   Contributed by Ron Guilmette (rfg@netcom.com).
+/* Operating system specific defines to be used when targeting GCC for some
+   generic System V Release 4 system.
+   Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+   Contributed by Ron Guilmette (rfg@segfault.us.com).
 
 This file is part of GNU CC.
 
@@ -127,13 +127,11 @@
 #undef	LIB_SPEC
 #define LIB_SPEC "%{!shared:%{!symbolic:-lc}}"
 
-/* Provide a LIB_SPEC_2 appropriate for svr4.  We don't want to include
-   libgcc, but various SVR4 implementations may want to specify some
-   dependencies.  */
-
-#undef  LIB_SPEC_2
-#define LIB_SPEC_2 \
-  "%{!shared:%{!symbolic:-lgcc}} %L %{!shared:%{!symbolic:-lgcc}}"
+/* Provide a LIBGCC_SPEC appropriate for svr4.  We also want to exclude
+   libgcc when -symbolic.  */
+
+#undef  LIBGCC_SPEC
+#define LIBGCC_SPEC "%{!shared:%{!symbolic:-lgcc}}"
 
 /* Provide an ENDFILE_SPEC appropriate for svr4.  Here we tack on our own
    magical crtend.o file (see crtstuff.c) which provides part of the
@@ -171,8 +169,8 @@
 #define LINK_SPEC "%{h*} %{V} %{v:%{!V:-V}} \
 		   %{b} %{Wl,*:%*} \
 		   %{static:-dn -Bstatic} \
-		   %{shared:-G -dy -z text} \
-		   %{symbolic:-Bsymbolic -G -dy -z text} \
+		   %{shared:-G -dy -z text %{!h*:%{o*:-h %*}}} \
+		   %{symbolic:-Bsymbolic -G -dy -z text %{!h*:%{o*:-h %*}}} \
 		   %{G:-G} \
 		   %{YP,*} \
 		   %{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
@@ -302,10 +300,11 @@
 do									\
   {									\
     static int sym_lineno = 1;						\
-    fprintf (file, ".stabn 68,0,%d,.LM%d-%s\n.LM%d:\n",			\
-	     line, sym_lineno, 						\
-	     XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0), 	\
-	     sym_lineno);						\
+    fprintf (file, ".stabn 68,0,%d,.LM%d-",				\
+	     line, sym_lineno);						\
+    assemble_name (file,						\
+		   XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
+    fprintf (file, "\n.LM%d:\n", sym_lineno);				\
     sym_lineno += 1;							\
   }									\
 while (0)
@@ -315,6 +314,14 @@
 
 #define DBX_FUNCTION_FIRST
 
+/* Generate a blank trailing N_SO to mark the end of the .o file, since
+   we can't depend upon the linker to mark .o file boundaries with
+   embedded stabs.  */
+
+#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME)			\
+  fprintf (FILE,							\
+	   "\t.text\n\t.stabs \"\",%d,0,0,.Letext\n.Letext:\n", N_SO)
+
 /* Define the actual types of some ANSI-mandated types.  (These
    definitions should work for most SVR4 systems).  */
 
@@ -495,8 +502,8 @@
    errors unless the .ctors and .dtors sections are marked as writable
    via the SHF_WRITE attribute.)  */
 
-#define CTORS_SECTION_ASM_OP	".section\t.ctors,\"aw\",@progbits"
-#define DTORS_SECTION_ASM_OP	".section\t.dtors,\"aw\",@progbits"
+#define CTORS_SECTION_ASM_OP	".section\t.ctors,\"aw\""
+#define DTORS_SECTION_ASM_OP	".section\t.dtors,\"aw\""
 
 /* On svr4, we *do* have support for the .init and .fini sections, and we
    can put stuff in there to be executed before and after `main'.  We let
@@ -567,7 +574,7 @@
 /* Switch into a generic section.
    This is currently only used to support section attributes.  */
 
-#define ASM_OUTPUT_SECTION(FILE, NAME) \
+#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME) \
   fprintf (FILE, ".section\t%s,\"a\",@progbits\n", NAME)
 
 /* A C statement (sans semicolon) to output an element in the table of
--- libc-sparc-5.3.12.orig/libc/elf/crt/config/sparc/linuxelf.h
+++ libc-sparc-5.3.12/libc/elf/crt/config/sparc/linuxelf.h
@@ -0,0 +1,127 @@
+/* Definitions for Intel 386 running Linux
+   Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+   Contributed by H.J. Lu (hjl@nynexst.com)
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if 0	/* The FSF has fixed the known bugs. But ....... */
+
+/* Linux has a hacked gas 1.38.1, which can handle repz, repnz
+ and fildll.  */
+
+#define GOOD_GAS
+#endif
+
+#define LINUX_ELF
+#define OBJECT_FORMAT_ELF
+#define INIT_SECTION_ASM_OP ".section \".init\""
+#define LINUX_DEFAULT_ELF
+#include "sparc/sparc.h"
+
+#define FINI_SECTION_ASM_OP ".section \".fini\""
+/* Don't assume anything about the header files. */
+#define NO_IMPLICIT_EXTERN_C
+
+/* This is tested by i386/gas.h.  */
+#define YES_UNDERSCORES
+
+#ifndef LINUX_ELF
+#if 0
+#include "sparc/gstabs.h"
+#endif
+#endif
+
+/* Specify predefined symbols in preprocessor.  */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dunix -Dsparc -D__sparc__ -D__ELF__ -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)"
+
+#undef CPP_SPEC
+#if TARGET_CPU_DEFAULT == 2
+#define CPP_SPEC "%{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}"
+#else
+#define CPP_SPEC "%{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}"
+#endif
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+#undef HAVE_ATEXIT
+#define HAVE_ATEXIT
+
+/* Linux uses ctype from glibc.a. I am not sure how complete it is.
+   For now, we play safe. It may change later. */
+
+#if 0
+#undef MULTIBYTE_CHARS
+#define MULTIBYTE_CHARS	1
+#endif
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} %{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}"
+
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC  \
+  "%{pg:gcrt0.o%s -static} %{!pg:%{p:gcrt0.o%s -static} %{!p:crt0.o%s %{g*:-static} %{static:-static}}}"
+
+
+/* There are conflicting reports about whether this system uses
+   a different assembler syntax.  wilson@cygnus.com says # is right.  */
+#undef COMMENT_BEGIN
+#define COMMENT_BEGIN "#"
+
+#undef ASM_APP_ON
+#define ASM_APP_ON "#APP\n"
+
+#undef ASM_APP_OFF
+#define ASM_APP_OFF "#NO_APP\n"
+
+/* Don't default to pcc-struct-return, because gcc is the only compiler, and
+   we want to retain compatibility with older gcc versions.  */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* We need that too. */
+#define HANDLE_SYSV_PRAGMA
+
+#undef LINK_SPEC
+
+/* We want to pass -v to linker */
+#if TARGET_CPU_DEFAULT == 2
+#define LINK_SPEC	"%{v:-dll-verbose} %{!m386:-m486}"
+#else
+#define LINK_SPEC	"%{v:-dll-verbose} %{m486:-m486}"
+#endif
+#undef LINK_SPEC
+#define LINK_SPEC  "%{h*} %{V} %{v:%{!V:-V}} \
+   %{b} %{Wl,*:%*} \
+   %{static:-dn -Bstatic} \
+   %{shared:-G -dy -z text %{!h*:%{o*:-h %*}}} \
+   %{symbolic:-Bsymbolic -G -dy -z text %{!h*:%{o*:-h %*}}} \
+   %{G:-G} \
+   %{YP,*} \
+   %{R*} \
+   %{Qy:} %{!Qn:-Qy}"
--- libc-sparc-5.3.12.orig/libc/elf/crt/config/sparc/sparc.h
+++ libc-sparc-5.3.12/libc/elf/crt/config/sparc/sparc.h
@@ -0,0 +1,2586 @@
+/* Definitions of target machine for GNU compiler, for Sun SPARC.
+   Copyright (C) 1987, 88, 89, 92, 94, 1995 Free Software Foundation, Inc.
+   Contributed by Michael Tiemann (tiemann@cygnus.com).
+   64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+   at Cygnus Support.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Note that some other tm.h files include this one and then override
+   many of the definitions that relate to assembler syntax.  */
+
+/* Sparc64 support has been added by trying to allow for a day when one
+   compiler can handle both v8 and v9.  There are a few cases where this
+   isn't doable, but keep them to a minimum!  Two macros are used to help out:
+   TARGET_V9 is used to select (at runtime) !v9-ness or v9-ness.
+   SPARCV9 is defined when compiling for sparc64 only.
+   In places where it is possible to choose between the two at runtime, use
+   TARGET_V9.  In places where it is currently not possible to select
+   between the two at runtime use SPARCV9.  Again, keep uses of SPARCV9 to a
+   minimum.  No attempt is made to support both v8 and v9 in the v9 compiler.
+
+   If a combination v8/v9 compiler is too slow, it should always be possible
+   to #define TARGET_V9 as 0 (and potentially other v9-only options), and
+   #undef SPARCV9.  */
+
+/* What architecture we're compiling for.  This must coincide with the
+   `arch_type' attribute in the .md file.  The names were chosen to avoid
+   potential misunderstandings with the various 32 bit flavors (v7, v8, etc.):
+   if we used ARCH_V9 then we'd want to use something like ARCH_V8 but that
+   could be misleading and ARCH_NOTV9 sounds klunky.  */
+enum arch_type { ARCH_32BIT, ARCH_64BIT };
+extern enum arch_type sparc_arch_type;
+
+/* Names to predefine in the preprocessor for this target machine.  */
+
+/* ??? The GCC_NEW_VARARGS macro is now obsolete, because gcc always uses
+   the right varags.h file when bootstrapping.  */
+
+#ifdef SPARCV9
+#define CPP_PREDEFINES \
+  "-Dsparc -Dsun -Dunix -D__sparc_v9__ \
+   -Asystem(unix) -Asystem(bsd) -Acpu(sparc64) -Amachine(sparc64)"
+#else
+#define CPP_PREDEFINES \
+  "-Dsparc -Dsun -Dunix -D__GCC_NEW_VARARGS__ \
+   -Asystem(unix) -Asystem(bsd) -Acpu(sparc) -Amachine(sparc)"
+#endif
+
+#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} %{g:-lg}}"
+
+/* Provide required defaults for linker -e and -d switches.  */
+
+#define LINK_SPEC \
+ "%{!shared:%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp} %{static:-Bstatic} \
+  %{assert*} %{shared:-assert pure-text}"
+
+/* Special flags to the Sun-4 assembler when using pipe for input.  */
+
+#define ASM_SPEC \
+  " %| %{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-k}}} %{keep-local-as-symbols:-L}"
+
+/* Define macros to distinguish architectures.  */
+
+#ifdef SPARCV9
+#define CPP_SPEC "\
+%{mint64:-D__INT_MAX__=9223372036854775807LL -D__LONG_MAX__=9223372036854775807LL} \
+%{mlong64:-D__LONG_MAX__=9223372036854775807LL} \
+"
+#else
+#define CPP_SPEC "\
+%{msparclite:-D__sparclite__} \
+%{mf930:-D__sparclite__} %{mf934:-D__sparclite__} \
+%{mv8:-D__sparc_v8__} \
+%{msupersparc:-D__supersparc__ -D__sparc_v8__}	\
+"
+#endif
+
+/* Prevent error on `-sun4' and `-target sun4' options.  */
+/* This used to translate -dalign to -malign, but that is no good
+   because it can't turn off the usual meaning of making debugging dumps.  */
+
+#define CC1_SPEC "%{sun4:} %{target:}"
+
+#ifdef SPARCV9
+#define PTRDIFF_TYPE "long long int"
+#define SIZE_TYPE "long long unsigned int"
+#else
+#define PTRDIFF_TYPE "int"
+/* In 2.4 it should work to delete this.
+   #define SIZE_TYPE "int"  */
+#endif
+
+/* ??? This should be 32 bits for v9 but what can we do?  */
+#define WCHAR_TYPE "short unsigned int"
+#define WCHAR_TYPE_SIZE 16
+#define MAX_WCHAR_TYPE_SIZE 16
+
+/* Show we can debug even without a frame pointer.  */
+#define CAN_DEBUG_WITHOUT_FP
+
+/* To make profiling work with -f{pic,PIC}, we need to emit the profiling
+   code into the rtl.  Also, if we are profiling, we cannot eliminate
+   the frame pointer (because the return address will get smashed).  */
+
+void sparc_override_options ();
+
+#define OVERRIDE_OPTIONS \
+  do {									\
+    if (profile_flag || profile_block_flag)				\
+      {									\
+	if (flag_pic)							\
+	  {								\
+	    char *pic_string = (flag_pic == 1) ? "-fpic" : "-fPIC";	\
+	    warning ("%s and profiling conflict: disabling %s",		\
+		     pic_string, pic_string);				\
+	    flag_pic = 0;						\
+	  }								\
+	flag_omit_frame_pointer = 0;					\
+      }									\
+    SUBTARGET_OVERRIDE_OPTIONS;						\
+    sparc_override_options ();						\
+  } while (0)
+
+/* This is meant to be redefined in the host dependent files.  */
+#define SUBTARGET_OVERRIDE_OPTIONS
+
+/* These compiler options take an argument.  We ignore -target for now.  */
+
+#define WORD_SWITCH_TAKES_ARG(STR)				\
+ (DEFAULT_WORD_SWITCH_TAKES_ARG (STR)				\
+  || !strcmp (STR, "target") || !strcmp (STR, "assert"))
+
+/* Print subsidiary information on the compiler version in use.  */
+
+#define TARGET_VERSION fprintf (stderr, " (sparc)");
+
+/* Generate DBX debugging information.  */
+
+#define DBX_DEBUGGING_INFO
+
+/* Run-time compilation parameters selecting different hardware subsets.  */
+
+extern int target_flags;
+
+/* Nonzero if we should generate code to use the fpu.  */
+#define MASK_FPU 1
+#define TARGET_FPU (target_flags & MASK_FPU)
+
+/* Nonzero if we should use FUNCTION_EPILOGUE.  Otherwise, we
+   use fast return insns, but lose some generality.  */
+#define MASK_EPILOGUE 2
+#define TARGET_EPILOGUE (target_flags & MASK_EPILOGUE)
+
+/* Nonzero if we should assume that double pointers might be unaligned.
+   This can happen when linking gcc compiled code with other compilers,
+   because the ABI only guarantees 4 byte alignment.  */
+#define MASK_UNALIGNED_DOUBLES 4
+#define TARGET_UNALIGNED_DOUBLES (target_flags & MASK_UNALIGNED_DOUBLES)
+
+/* ??? Bits 0x18 are currently unused.  */
+
+/* Nonzero means we should schedule code for the TMS390Z55 SuperSparc chip.  */
+#define MASK_SUPERSPARC 0x20
+#define TARGET_SUPERSPARC (target_flags & MASK_SUPERSPARC)
+
+/* Nonzero means that we should generate code for a v8 sparc.  */
+#define MASK_V8 0x40
+#define TARGET_V8 (target_flags & MASK_V8)
+
+/* Nonzero means that we should generate code for a sparclite.
+   This enables the sparclite specific instructions, but does not affect
+   whether FPU instructions are emitted.  */
+#define MASK_SPARCLITE 0x80
+#define TARGET_SPARCLITE (target_flags & MASK_SPARCLITE)
+
+/* Nonzero means that we should generate code using a flat register window
+   model, i.e. no save/restore instructions are generated, in the most
+   efficient manner.  This code is not compatible with normal sparc code.  */
+/* This is not a user selectable option yet, because it requires changes
+   that are not yet switchable via command line arguments.  */
+/* ??? This flag is deprecated and may disappear at some point.  */
+#define MASK_FRW 0x100
+#define TARGET_FRW (target_flags & MASK_FRW)
+
+/* Nonzero means that we should generate code using a flat register window
+   model, i.e. no save/restore instructions are generated, but which is
+   compatible with normal sparc code.   This is the same as above, except
+   that the frame pointer is %i7 instead of %fp.  */
+/* ??? This use to be named TARGET_FRW_COMPAT.  At some point TARGET_FRW will
+   go away, but until that time only use this one when necessary.
+   -mflat sets both.  */
+#define MASK_FLAT 0x200
+#define TARGET_FLAT (target_flags & MASK_FLAT)
+
+/* Nonzero means use the registers that the Sparc ABI reserves for
+   application software.  This is the default for v8, but not v9.  */
+#define MASK_APP_REGS 0x400
+#define TARGET_APP_REGS (target_flags & MASK_APP_REGS)
+
+/*  Option to select how quad word floating point is implemented.
+    When TARGET_HARD_QUAD is true, we use the hardware quad instructions.
+    Otherwise, we use the SPARC ABI quad library functions.  */
+#define MASK_HARD_QUAD 0x800
+#define TARGET_HARD_QUAD (target_flags & MASK_HARD_QUAD)
+
+/* Nonzero if we're compiling for 64 bit sparc.  */
+#define MASK_V9 0x1000
+#define TARGET_V9 (target_flags & MASK_V9)
+
+/* Nonzero if ints are 64 bits.
+   This automatically implies longs are 64 bits too.
+   This option is for v9 only.  */
+#define MASK_INT64 0x2000
+#define TARGET_INT64 (target_flags & MASK_INT64)
+
+/* Nonzero if longs are 64 bits.
+   This option is for v9 only.  */
+#define MASK_LONG64 0x4000
+#define TARGET_LONG64 (target_flags & MASK_LONG64)
+
+/* Nonzero if pointers are 64 bits.
+   This is not a user selectable option, though it may be one day -
+   so it is used to determine pointer size instead of an architecture flag.  */
+#define MASK_PTR64 0x8000
+#define TARGET_PTR64 (target_flags & MASK_PTR64)
+
+/* Nonzero if we are generating code to be tested in a 32 bit environment.
+   Hence, we assume the upper 32 bits of symbolic addresses are zero, and
+   avoid generating %uhi and %ulo terms.
+   Pointers are still 64 bits though!  This option is for v9 only.  */
+/* ??? This option is deprecated.  Try to use -mmedlow.  */
+#define MASK_ENV32 0x10000
+#define TARGET_ENV32 (target_flags & MASK_ENV32)
+
+/* Memory models.
+   Two memory models are supported:
+   TARGET_MEDLOW: 32 bit address space, top 32 bits = 0
+                  (pointers still 64 bits)
+   TARGET_MEDANY: 32 bit address space, data segment loaded anywhere
+                  (use %g4 as offset).
+   TARGET_FULLANY: not supported yet.
+   These options are for v9 only.  All mask values are nonzero so the v8
+   compiler can assume this stuff won't interfere.  */
+#define MASK_MEDLOW 0x20000
+#define MASK_MEDANY 0x40000
+#define MASK_FULLANY 0x60000
+#define MASK_CODE_MODEL (MASK_MEDLOW + MASK_MEDANY)
+#define TARGET_MEDLOW ((target_flags & MASK_CODE_MODEL) == MASK_MEDLOW)
+#define TARGET_MEDANY ((target_flags & MASK_CODE_MODEL) == MASK_MEDANY)
+#define TARGET_FULLANY ((target_flags & MASK_CODE_MODEL) == MASK_FULLANY)
+
+/* ??? There are hardcoded references to this reg in the .md file.  */
+#define MEDANY_BASE_REG "%g4"
+
+/* Non-zero means use a stack bias of 2047.  Stack offsets are obtained by
+   adding 2047 to %sp.  This option is for v9 only and is the default.  */
+#define MASK_STACK_BIAS 0x80000
+#define TARGET_STACK_BIAS (target_flags & MASK_STACK_BIAS)
+
+/* Macro to define tables used to set the flags.
+   This is a list in braces of pairs in braces,
+   each pair being { "NAME", VALUE }
+   where VALUE is the bits to set or minus the bits to clear.
+   An empty string NAME is used to identify the default VALUE.  */
+
+/* The Fujitsu MB86930 is the original sparclite chip, with no fpu.
+   The Fujitsu MB86934 is the recent sparclite chip, with an fpu.
+   We use -mf930 and -mf934 options to choose which.
+   ??? These should perhaps be -mcpu= options.  */
+
+#define TARGET_SWITCHES  \
+  { {"fpu", MASK_FPU},			\
+    {"no-fpu", -MASK_FPU},		\
+    {"hard-float", MASK_FPU},		\
+    {"soft-float", -MASK_FPU},		\
+    {"epilogue", MASK_EPILOGUE},	\
+    {"no-epilogue", -MASK_EPILOGUE},	\
+    {"unaligned-doubles", MASK_UNALIGNED_DOUBLES}, \
+    {"no-unaligned-doubles", -MASK_UNALIGNED_DOUBLES}, \
+    {"supersparc", MASK_SUPERSPARC+MASK_V8},	\
+    {"cypress", -MASK_SUPERSPARC-MASK_V8},	\
+    {"v8", MASK_V8},			\
+    {"no-v8", -MASK_V8},		\
+    {"sparclite", MASK_SPARCLITE},	\
+    {"no-sparclite", -MASK_SPARCLITE},	\
+    {"f930", MASK_SPARCLITE},		\
+    {"f930", -MASK_FPU},		\
+    {"f934", MASK_SPARCLITE},		\
+    {"flat", MASK_FRW+MASK_FLAT},	\
+    {"no-flat", -(MASK_FRW+MASK_FLAT)},	\
+    {"app-regs", MASK_APP_REGS},	\
+    {"no-app-regs", -MASK_APP_REGS},	\
+    {"hard-quad-float", MASK_HARD_QUAD}, \
+    {"soft-quad-float", -MASK_HARD_QUAD}, \
+    SUBTARGET_SWITCHES			\
+    V9_SWITCHES				\
+    { "", TARGET_DEFAULT}}
+
+#define TARGET_DEFAULT (MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU)
+
+/* This is meant to be redefined in the host dependent files */
+#define SUBTARGET_SWITCHES
+
+/* ??? Until we support a combination v8/v9 compiler, the v9 specific options
+   are only defined for the v9 compiler.  */
+#ifdef SPARCV9
+#define V9_SWITCHES \
+/*  {"v9", MASK_V9}, */			\
+    {"int64", MASK_INT64+MASK_LONG64},	\
+    {"int32", -MASK_INT64},		\
+    {"int32", MASK_LONG64},		\
+    {"long64", -MASK_INT64},		\
+    {"long64", MASK_LONG64},		\
+    {"long32", -(MASK_INT64+MASK_LONG64)}, \
+/*  {"ptr64", MASK_PTR64}, */		\
+/*  {"ptr32", -MASK_PTR64}, */		\
+    {"stack-bias", MASK_STACK_BIAS},	\
+    {"no-stack-bias", -MASK_STACK_BIAS}, \
+    {"medlow", -MASK_CODE_MODEL},	\
+    {"medlow", MASK_MEDLOW},		\
+    {"medany", -MASK_CODE_MODEL},	\
+    {"medany", MASK_MEDANY},
+#else
+#define V9_SWITCHES
+#endif
+
+/* target machine storage layout */
+
+/* Define for cross-compilation to a sparc target with no TFmode from a host
+   with a different float format (e.g. VAX).  */
+#define REAL_ARITHMETIC
+
+/* Define this if most significant bit is lowest numbered
+   in instructions that operate on numbered bit-fields.  */
+#define BITS_BIG_ENDIAN 1
+
+/* Define this if most significant byte of a word is the lowest numbered.  */
+/* This is true on the SPARC.  */
+#define BYTES_BIG_ENDIAN 1
+
+/* Define this if most significant word of a multiword number is the lowest
+   numbered.  */
+/* Doubles are stored in memory with the high order word first.  This
+   matters when cross-compiling.  */
+#define WORDS_BIG_ENDIAN 1
+
+/* number of bits in an addressable storage unit */
+#define BITS_PER_UNIT 8
+
+/* Width in bits of a "word", which is the contents of a machine register.
+   Note that this is not necessarily the width of data type `int';
+   if using 16-bit ints on a 68000, this would still be 32.
+   But on a machine with 16-bit registers, this would be 16.  */
+#define BITS_PER_WORD		(TARGET_V9 ? 64 : 32)
+#define MAX_BITS_PER_WORD	64
+
+/* Width of a word, in units (bytes).  */
+#define UNITS_PER_WORD		(TARGET_V9 ? 8 : 4)
+#define MIN_UNITS_PER_WORD	4
+
+/* Now define the sizes of the C data types.  */
+
+#define SHORT_TYPE_SIZE		16
+#define INT_TYPE_SIZE		(TARGET_INT64 ? 64 : 32)
+#define LONG_TYPE_SIZE		(TARGET_LONG64 ? 64 : 32)
+#define LONG_LONG_TYPE_SIZE	64
+#define FLOAT_TYPE_SIZE		32
+#define DOUBLE_TYPE_SIZE	64
+
+#define MAX_INT_TYPE_SIZE	64
+#define MAX_LONG_TYPE_SIZE	64
+
+#ifdef SPARCV9
+/* ??? This does not work in SunOS 4.x, so it is not enabled here.
+   Instead, it is enabled in sol2.h, because it does work under Solaris.  */
+/* Define for support of TFmode long double and REAL_ARITHMETIC.
+   Sparc ABI says that long double is 4 words.  */
+#define LONG_DOUBLE_TYPE_SIZE 128
+#endif
+
+/* Width in bits of a pointer.
+   See also the macro `Pmode' defined below.  */
+#define POINTER_SIZE (TARGET_PTR64 ? 64 : 32)
+
+/* Allocation boundary (in *bits*) for storing arguments in argument list.  */
+#define PARM_BOUNDARY (TARGET_V9 ? 64 : 32)
+
+/* Boundary (in *bits*) on which stack pointer should be aligned.  */
+#define STACK_BOUNDARY (TARGET_V9 ? 128 : 64)
+
+/* ALIGN FRAMES on double word boundaries */
+
+#define SPARC_STACK_ALIGN(LOC) \
+  (TARGET_V9 ? (((LOC)+15) & ~15) : (((LOC)+7) & ~7))
+
+/* Allocation boundary (in *bits*) for the code of a function.  */
+#define FUNCTION_BOUNDARY 32
+
+/* Alignment of field after `int : 0' in a structure.  */
+/* ??? Should this be based on TARGET_INT64?  */
+#define EMPTY_FIELD_BOUNDARY (TARGET_V9 ? 64 : 32)
+
+/* Every structure's size must be a multiple of this.  */
+#define STRUCTURE_SIZE_BOUNDARY 8
+
+/* A bitfield declared as `int' forces `int' alignment for the struct.  */
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+/* No data type wants to be aligned rounder than this.  */
+#define BIGGEST_ALIGNMENT (TARGET_V9 ? 128 : 64)
+
+/* The best alignment to use in cases where we have a choice.  */
+#define FASTEST_ALIGNMENT 64
+
+/* Make strings word-aligned so strcpy from constants will be faster.  */
+#define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
+  ((TREE_CODE (EXP) == STRING_CST	\
+    && (ALIGN) < FASTEST_ALIGNMENT)	\
+   ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Make arrays of chars word-aligned for the same reasons.  */
+#define DATA_ALIGNMENT(TYPE, ALIGN)		\
+  (TREE_CODE (TYPE) == ARRAY_TYPE		\
+   && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
+   && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Set this nonzero if move instructions will actually fail to work
+   when given unaligned data.  */
+#define STRICT_ALIGNMENT 1
+
+/* Things that must be doubleword aligned cannot go in the text section,
+   because the linker fails to align the text section enough!
+   Put them in the data section.  This macro is only used in this file.  */
+#define MAX_TEXT_ALIGN 32
+
+/* This forces all variables and constants to the data section when PIC.
+   This is because the SunOS 4 shared library scheme thinks everything in
+   text is a function, and patches the address to point to a loader stub.  */
+/* This is defined to zero for every system which doesn't use the a.out object
+   file format.  */
+#ifndef SUNOS4_SHARED_LIBRARIES
+#define SUNOS4_SHARED_LIBRARIES 0
+#endif
+
+/* This is defined differently for v9 in a cover file.  */
+#define SELECT_SECTION(T,RELOC)						\
+{									\
+  if (TREE_CODE (T) == VAR_DECL)					\
+    {									\
+      if (TREE_READONLY (T) && ! TREE_SIDE_EFFECTS (T)			\
+	  && DECL_INITIAL (T)						\
+	  && (DECL_INITIAL (T) == error_mark_node			\
+	      || TREE_CONSTANT (DECL_INITIAL (T)))			\
+	  && DECL_ALIGN (T) <= MAX_TEXT_ALIGN				\
+	  && ! (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES)))	\
+	text_section ();						\
+      else								\
+	data_section ();						\
+    }									\
+  else if (TREE_CODE (T) == CONSTRUCTOR)				\
+    {									\
+      if (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES))		\
+	data_section ();						\
+    }									\
+  else if (*tree_code_type[(int) TREE_CODE (T)] == 'c')			\
+    {									\
+      if ((TREE_CODE (T) == STRING_CST && flag_writable_strings)	\
+	  || TYPE_ALIGN (TREE_TYPE (T)) > MAX_TEXT_ALIGN		\
+	  || (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES)))	\
+	data_section ();						\
+      else								\
+	text_section ();						\
+    }									\
+}
+
+/* Use text section for a constant
+   unless we need more alignment than that offers.  */
+/* This is defined differently for v9 in a cover file.  */
+#define SELECT_RTX_SECTION(MODE, X)		\
+{						\
+  if (GET_MODE_BITSIZE (MODE) <= MAX_TEXT_ALIGN \
+      && ! (flag_pic && (symbolic_operand (X) || SUNOS4_SHARED_LIBRARIES)))  \
+    text_section ();				\
+  else						\
+    data_section ();				\
+}
+
+/* Standard register usage.  */
+
+/* Number of actual hardware registers.
+   The hardware registers are assigned numbers for the compiler
+   from 0 to just below FIRST_PSEUDO_REGISTER.
+   All registers that the compiler knows about must be given numbers,
+   even those that are not normally considered general registers.
+
+   SPARC has 32 integer registers and 32 floating point registers.
+   64 bit SPARC has 32 additional fp regs, but the odd numbered ones are not
+   accessible.  We still account for them to simplify register computations
+   (eg: in CLASS_MAX_NREGS).  There are also 4 fp condition code registers, so
+   32+32+32+4 == 100.
+   Register 0 is used as the integer condition code register.  */
+
+#ifdef SPARCV9
+#define FIRST_PSEUDO_REGISTER 100
+#else
+#define FIRST_PSEUDO_REGISTER 64
+#endif
+
+/* 1 for registers that have pervasive standard uses
+   and are not available for the register allocator.
+   g0 is used for the condition code and not to represent %g0, which is
+   hardwired to 0, so reg 0 is *not* fixed.
+   On non-v9 systems:
+   g1 is free to use as temporary.
+   g2-g4 are reserved for applications.  Gcc normally uses them as
+   temporaries, but this can be disabled via the -mno-app-regs option.
+   g5 through g7 are reserved for the operating system.
+   On v9 systems:
+   g1 and g5 are free to use as temporaries.
+   g2-g4 are reserved for applications (the compiler will not normally use
+   them, but they can be used as temporaries with -mapp-regs).
+   g6-g7 are reserved for the operating system.
+   ??? Register 1 is used as a temporary by the 64 bit sethi pattern, so must
+   currently be a fixed register until this pattern is rewritten.
+   Register 1 is also used when restoring call-preserved registers in large
+   stack frames.  */
+
+#ifdef SPARCV9
+#define FIXED_REGISTERS  \
+ {0, 1, 1, 1, 1, 0, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 1,	\
+				\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+				\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+				\
+  0, 0, 0, 0}
+#else
+#define FIXED_REGISTERS  \
+ {0, 0, 0, 0, 0, 1, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 1,	\
+				\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0}
+#endif
+
+/* 1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.  */
+
+#ifdef SPARCV9
+#define CALL_USED_REGISTERS  \
+ {1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 1,	\
+				\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+				\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+				\
+  1, 1, 1, 1}
+#else
+#define CALL_USED_REGISTERS  \
+ {1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 1,	\
+				\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1}
+#endif
+
+/* If !TARGET_FPU, then make the fp registers fixed so that they won't
+   be allocated.  On v9, also make the fp cc regs fixed.  */
+
+#define CONDITIONAL_REGISTER_USAGE				\
+do								\
+  {								\
+    if (! TARGET_FPU)						\
+      {								\
+	int regno;						\
+	for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno++) \
+	  fixed_regs[regno] = 1;				\
+      }								\
+    if (! TARGET_APP_REGS)					\
+      {								\
+	fixed_regs[2] = 1;					\
+	fixed_regs[3] = 1;					\
+	fixed_regs[4] = 1;					\
+      }								\
+    else							\
+      {								\
+	fixed_regs[2] = 0;					\
+	fixed_regs[3] = 0;					\
+	fixed_regs[4] = TARGET_MEDANY != 0;			\
+      }								\
+    if (TARGET_FLAT)						\
+      {								\
+	/* Let the compiler believe the frame pointer is still	\
+	   %fp, but output it as %i7.  */			\
+	fixed_regs[31] = 1;					\
+	reg_names[FRAME_POINTER_REGNUM] = "%i7";		\
+	/* ??? This is a hack to disable leaf functions.  */	\
+	global_regs[7] = 1;					\
+      }								\
+    if (profile_block_flag)					\
+      {								\
+	/* %g1 and %g2 must be fixed, because BLOCK_PROFILER	\
+	    uses them.  */					\
+	fixed_regs[1] = 1;					\
+	fixed_regs[2] = 1;					\
+      }								\
+  }								\
+while (0)
+
+/* Return number of consecutive hard regs needed starting at reg REGNO
+   to hold something of mode MODE.
+   This is ordinarily the length in words of a value of mode MODE
+   but can be less for certain modes in special long registers.
+
+   On SPARC, ordinary registers hold 32 bits worth;
+   this means both integer and floating point registers.
+   On v9, integer regs hold 64 bits worth; floating point regs hold
+   32 bits worth (this includes the new fp regs as even the odd ones are
+   included in the hard register count).  */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+  (TARGET_V9								\
+   ?  ((REGNO) < 32							\
+       ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD	\
+       : (GET_MODE_SIZE (MODE) + 3) / 4)				\
+   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+
+/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
+   See sparc.c for how we initialize this.  */
+extern int *hard_regno_mode_classes;
+extern int sparc_mode_class[];
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+  ((hard_regno_mode_classes[REGNO] & sparc_mode_class[MODE]) != 0)
+
+/* Value is 1 if it is a good idea to tie two pseudo registers
+   when one has mode MODE1 and one has mode MODE2.
+   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+   for any hard reg, then this must be 0 for correct output.
+
+   For V9: SFmode can't be combined with other float modes, because they can't
+   be allocated to the %d registers.  Also, DFmode won't fit in odd %f
+   registers, but SFmode will.  */
+#define MODES_TIEABLE_P(MODE1, MODE2) \
+  ((MODE1) == (MODE2)						\
+   || (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)		\
+       && (! TARGET_V9						\
+	   || (GET_MODE_CLASS (MODE1) != MODE_FLOAT		\
+	       || (MODE1 != SFmode && MODE2 != SFmode)))))
+
+/* Specify the registers used for certain standard purposes.
+   The values of these macros are register numbers.  */
+
+/* SPARC pc isn't overloaded on a register that the compiler knows about.  */
+/* #define PC_REGNUM  */
+
+/* Register to use for pushing function arguments.  */
+#define STACK_POINTER_REGNUM 14
+
+/* Actual top-of-stack address is 92/136 greater than the contents of the
+   stack pointer register for !v9/v9.  That is:
+   - !v9: 64 bytes for the in and local registers, 4 bytes for structure return
+     address, and 24 bytes for the 6 register parameters.
+   - v9: 128 bytes for the in and local registers + 8 bytes reserved.  */
+#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(0)
+
+/* The stack bias (amount by which the hardware register is offset by).  */
+#define SPARC_STACK_BIAS (TARGET_STACK_BIAS ? 2047 : 0)
+
+/* Base register for access to local variables of the function.  */
+#define FRAME_POINTER_REGNUM 30
+
+#if 0
+/* Register that is used for the return address.  */
+#define RETURN_ADDR_REGNUM 15
+#endif
+
+/* Value should be nonzero if functions must have frame pointers.
+   Zero means the frame pointer need not be set up (and parms
+   may be accessed via the stack pointer) in functions that seem suitable.
+   This is computed in `reload', in reload1.c.
+   Used in flow.c, global.c, and reload1.c.
+
+   Being a non-leaf function does not mean a frame pointer is needed in the
+   flat window model.  However, the debugger won't be able to backtrace through
+   us with out it.  */
+#define FRAME_POINTER_REQUIRED \
+  (TARGET_FRW ? (current_function_calls_alloca || current_function_varargs \
+		 || !leaf_function_p ()) \
+   : ! (leaf_function_p () && only_leaf_regs_used ()))
+
+/* C statement to store the difference between the frame pointer
+   and the stack pointer values immediately after the function prologue.
+
+   Note, we always pretend that this is a leaf function because if
+   it's not, there's no point in trying to eliminate the
+   frame pointer.  If it is a leaf function, we guessed right!  */
+#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
+  ((VAR) = (TARGET_FRW ? sparc_flat_compute_frame_size (get_frame_size ()) \
+	    : compute_frame_size (get_frame_size (), 1)))
+
+/* Base register for access to arguments of the function.  */
+#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
+
+/* Register in which static-chain is passed to a function.  This must
+   not be a register used by the prologue.
+   ??? v9: Since %g2 is reserved but %g5 is available, perhaps use %g5.  */
+#define STATIC_CHAIN_REGNUM 2
+
+/* Register which holds offset table for position-independent
+   data references.  */
+
+#define PIC_OFFSET_TABLE_REGNUM 23
+
+#define INITIALIZE_PIC initialize_pic ()
+#define FINALIZE_PIC finalize_pic ()
+
+/* Sparc ABI says that quad-precision floats and all structures are returned
+   in memory.
+   For v9, all aggregates are returned in memory.  */
+#define RETURN_IN_MEMORY(TYPE)				\
+  (TYPE_MODE (TYPE) == BLKmode				\
+   || (! TARGET_V9 && (TYPE_MODE (TYPE) == TFmode	\
+		       || TYPE_MODE (TYPE) == TCmode)))
+
+/* Functions which return large structures get the address
+   to place the wanted value at offset 64 from the frame.
+   Must reserve 64 bytes for the in and local registers.
+   v9: Functions which return large structures get the address to place the
+   wanted value from an invisible first argument.  */
+/* Used only in other #defines in this file.  */
+#define STRUCT_VALUE_OFFSET 64
+
+#define STRUCT_VALUE \
+  (TARGET_V9						\
+   ? 0							\
+   : gen_rtx (MEM, Pmode,				\
+	      gen_rtx (PLUS, Pmode, stack_pointer_rtx,	\
+		       gen_rtx (CONST_INT, VOIDmode, STRUCT_VALUE_OFFSET))))
+#define STRUCT_VALUE_INCOMING \
+  (TARGET_V9						\
+   ? 0							\
+   : gen_rtx (MEM, Pmode,				\
+	      gen_rtx (PLUS, Pmode, frame_pointer_rtx,	\
+		       gen_rtx (CONST_INT, VOIDmode, STRUCT_VALUE_OFFSET))))
+
+/* Define the classes of registers for register constraints in the
+   machine description.  Also define ranges of constants.
+
+   One of the classes must always be named ALL_REGS and include all hard regs.
+   If there is more than one class, another class must be named NO_REGS
+   and contain no registers.
+
+   The name GENERAL_REGS must be the name of a class (or an alias for
+   another name such as ALL_REGS).  This is the class of registers
+   that is allowed by "g" or "r" in a register constraint.
+   Also, registers outside this class are allocated only when
+   instructions express preferences for them.
+
+   The classes must be numbered in nondecreasing order; that is,
+   a larger-numbered class must never be contained completely
+   in a smaller-numbered class.
+
+   For any two classes, it is very desirable that there be another
+   class that represents their union.  */
+
+/* The SPARC has two kinds of registers, general and floating point.
+
+   For v9 we must distinguish between the upper and lower floating point
+   registers because the upper ones can't hold SFmode values.
+   HARD_REGNO_MODE_OK won't help here because reload assumes that register(s)
+   satisfying a group need for a class will also satisfy a single need for
+   that class.  EXTRA_FP_REGS is a bit of a misnomer as it covers all 64 fp
+   regs.
+
+   It is important that one class contains all the general and all the standard
+   fp regs.  Otherwise find_reg() won't properly allocate int regs for moves,
+   because reg_class_record() will bias the selection in favor of fp regs,
+   because reg_class_subunion[GENERAL_REGS][FP_REGS] will yield FP_REGS,
+   because FP_REGS > GENERAL_REGS.
+
+   It is also important that one class contain all the general and all the
+   fp regs.  Otherwise when spilling a DFmode reg, it may be from EXTRA_FP_REGS
+   but find_reloads() may use class GENERAL_OR_FP_REGS. This will cause
+   allocate_reload_reg() to bypass it causing an abort because the compiler
+   thinks it doesn't have a spill reg when in fact it does.
+
+   v9 also has 4 floating point condition code registers.  Since we don't
+   have a class that is the union of FPCC_REGS with either of the others,
+   it is important that it appear first.  Otherwise the compiler will die
+   trying to compile _fixunsdfsi because fix_truncdfsi2 won't match its
+   constraints.  */
+
+#ifdef SPARCV9
+enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS,
+		 GENERAL_OR_FP_REGS, GENERAL_OR_EXTRA_FP_REGS,
+		 ALL_REGS, LIM_REG_CLASSES };
+#else
+enum reg_class { NO_REGS, GENERAL_REGS, FP_REGS, ALL_REGS, LIM_REG_CLASSES };
+#endif
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file.   */
+
+#ifdef SPARCV9
+#define REG_CLASS_NAMES \
+  { "NO_REGS", "FPCC_REGS", "GENERAL_REGS", "FP_REGS", "EXTRA_FP_REGS", \
+    "GENERAL_OR_FP_REGS", "GENERAL_OR_EXTRA_FP_REGS", "ALL_REGS" }
+#else
+#define REG_CLASS_NAMES \
+  { "NO_REGS", "GENERAL_REGS", "FP_REGS", "ALL_REGS" }
+#endif
+
+/* Define which registers fit in which classes.
+   This is an initializer for a vector of HARD_REG_SET
+   of length N_REG_CLASSES.  */
+
+#ifdef SPARCV9
+#define REG_CLASS_CONTENTS \
+  {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {-2, 0, 0, 0}, \
+   {0, -1, 0, 0}, {0, -1, -1, 0}, {-2, -1, 0, 0}, {-2, -1, -1, 0}, \
+   {-2, -1, -1, 0xf}}
+#else
+#if 0 && defined (__GNUC__)
+#define REG_CLASS_CONTENTS {0LL, 0xfffffffeLL, 0xffffffff00000000LL, 0xfffffffffffffffeLL}
+#else
+#define REG_CLASS_CONTENTS {{0, 0}, {-2, 0}, {0, -1}, {-2, -1}}
+#endif
+#endif
+
+/* The same information, inverted:
+   Return the class number of the smallest class containing
+   reg number REGNO.  This could be a conditional expression
+   or could index an array.  */
+
+#ifdef SPARCV9
+#define REGNO_REG_CLASS(REGNO) \
+  ((REGNO) == 0 ? NO_REGS		\
+   : (REGNO) < 32 ? GENERAL_REGS	\
+   : (REGNO) < 64 ? FP_REGS		\
+   : (REGNO) < 96 ? EXTRA_FP_REGS	\
+   : FPCC_REGS)
+#else
+#define REGNO_REG_CLASS(REGNO) \
+  ((REGNO) >= 32 ? FP_REGS : (REGNO) == 0 ? NO_REGS : GENERAL_REGS)
+#endif
+
+/* This is the order in which to allocate registers normally.  
+   
+   We put %f0/%f1 last among the float registers, so as to make it more
+   likely that a pseudo-register which dies in the float return register
+   will get allocated to the float return register, thus saving a move
+   instruction at the end of the function.
+
+   On v9, the float registers are ordered a little "funny" because some
+   of them (%f16-%f47) are call-preserved.  */
+#ifdef SPARCV9
+#define REG_ALLOC_ORDER \
+{ 8, 9, 10, 11, 12, 13,			\
+  15, 16, 17, 18, 19, 20, 21, 22,	\
+  23, 24, 25, 26, 27, 28, 29, 31,	\
+  34, 35, 36, 37, 38, 39,		/* %f2-%f7 */   \
+  40, 41, 42, 43, 44, 45, 46, 47,	/* %f8-%f15 */  \
+  80, 81, 82, 83, 84, 85, 86, 87,	/* %f48-%f55 */ \
+  88, 89, 90, 91, 92, 93, 94, 95,	/* %f56-%f63 */ \
+  48, 49, 50, 51, 52, 53, 54, 55,	/* %f16-%f23 */ \
+  56, 57, 58, 59, 60, 61, 62, 63,	/* %f24-%f31 */ \
+  64, 65, 66, 67, 68, 69, 70, 71,	/* %f32-%f39 */ \
+  72, 73, 74, 75, 76, 77, 78, 79,	/* %f40-%f47 */ \
+  32, 33,				/* %f0,%f1 */   \
+  96, 97, 98, 99,			/* %fcc0-3 */   \
+  1, 5, 2, 3, 4, 6, 7, 0, 14, 30}
+#else
+#define REG_ALLOC_ORDER \
+{ 8, 9, 10, 11, 12, 13, 2, 3, 		\
+  15, 16, 17, 18, 19, 20, 21, 22, 	\
+  23, 24, 25, 26, 27, 28, 29, 31,	\
+  34, 35, 36, 37, 38, 39,		\
+  40, 41, 42, 43, 44, 45, 46, 47,	\
+  48, 49, 50, 51, 52, 53, 54, 55,	\
+  56, 57, 58, 59, 60, 61, 62, 63,	\
+  32, 33,				\
+  1, 4, 5, 6, 7, 0, 14, 30}
+#endif
+
+/* This is the order in which to allocate registers for
+   leaf functions.  If all registers can fit in the "i" registers,
+   then we have the possibility of having a leaf function.
+   v9: The floating point registers are ordered a little "funny" because some
+   of them (%f16-%f47) are call-preserved.   */
+#ifdef SPARCV9
+#define REG_LEAF_ALLOC_ORDER \
+{ 24, 25, 26, 27, 28, 29,		\
+  15, 8, 9, 10, 11, 12, 13,		\
+  16, 17, 18, 19, 20, 21, 22, 23,	\
+  34, 35, 36, 37, 38, 39,		\
+  40, 41, 42, 43, 44, 45, 46, 47,	\
+  80, 81, 82, 83, 84, 85, 86, 87,	\
+  88, 89, 90, 91, 92, 93, 94, 95,	\
+  48, 49, 50, 51, 52, 53, 54, 55,	\
+  56, 57, 58, 59, 60, 61, 62, 63,	\
+  64, 65, 66, 67, 68, 69, 70, 71,	\
+  72, 73, 74, 75, 76, 77, 78, 79,	\
+  32, 33,				\
+  96, 97, 98, 99,			\
+  1, 5, 2, 3, 4, 6, 7, 0, 14, 30, 31}
+#else
+#define REG_LEAF_ALLOC_ORDER \
+{ 2, 3, 24, 25, 26, 27, 28, 29,		\
+  15, 8, 9, 10, 11, 12, 13,		\
+  16, 17, 18, 19, 20, 21, 22, 23,	\
+  34, 35, 36, 37, 38, 39,		\
+  40, 41, 42, 43, 44, 45, 46, 47,	\
+  48, 49, 50, 51, 52, 53, 54, 55,	\
+  56, 57, 58, 59, 60, 61, 62, 63,	\
+  32, 33,				\
+  1, 4, 5, 6, 7, 0, 14, 30, 31}
+#endif
+
+#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
+
+/* ??? %g7 is not a leaf register to effectively #undef LEAF_REGISTERS when
+   -mflat is used.  Function only_leaf_regs_used will return 0 if a global
+   register is used and is not permitted in a leaf function.  We make %g7
+   a global reg if -mflat and voila.  Since %g7 is a system register and is
+   fixed it won't be used by gcc anyway.  */
+#ifdef SPARCV9
+#define LEAF_REGISTERS \
+{ 1, 1, 1, 1, 1, 1, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  1, 1, 1, 1, 1, 1, 0, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1}
+#else
+#define LEAF_REGISTERS \
+{ 1, 1, 1, 1, 1, 1, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  1, 1, 1, 1, 1, 1, 0, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1}
+#endif
+
+extern char leaf_reg_remap[];
+#define LEAF_REG_REMAP(REGNO) (leaf_reg_remap[REGNO])
+
+/* The class value for index registers, and the one for base regs.  */
+#define INDEX_REG_CLASS GENERAL_REGS
+#define BASE_REG_CLASS GENERAL_REGS
+
+/* Local macro to handle the two v9 classes of FP regs.  */
+#ifdef SPARCV9
+#define FP_REG_CLASS_P(CLASS) ((CLASS) == FP_REGS || (CLASS) == EXTRA_FP_REGS)
+#else
+#define FP_REG_CLASS_P(CLASS) ((CLASS) == FP_REGS)
+#endif
+
+/* Get reg_class from a letter such as appears in the machine description.  */
+
+#ifdef SPARCV9
+#define REG_CLASS_FROM_LETTER(C) \
+  ((C) == 'f' ? FP_REGS		\
+   : (C) == 'e' ? EXTRA_FP_REGS	\
+   : (C) == 'c' ? FPCC_REGS	\
+   : NO_REGS)
+#else
+/* Coerce v9's 'e' class to 'f', so we can use 'e' in the .md file for
+   v8 and v9.  */
+#define REG_CLASS_FROM_LETTER(C) \
+  ((C) == 'f' ? FP_REGS : (C) == 'e' ? FP_REGS : NO_REGS)
+#endif
+
+/* The letters I, J, K, L and M in a register constraint string
+   can be used to stand for particular ranges of immediate operands.
+   This macro defines what the ranges are.
+   C is the letter, and VALUE is a constant value.
+   Return 1 if VALUE is in the range specified by C.
+
+   For SPARC, `I' is used for the range of constants an insn
+   can actually contain.
+   `J' is used for the range which is just zero (since that is R0).
+   `K' is used for constants which can be loaded with a single sethi insn.  */
+
+#define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x1000) < 0x2000)
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C)  \
+  ((C) == 'I' ? (unsigned) ((VALUE) + 0x1000) < 0x2000	\
+   : (C) == 'J' ? (VALUE) == 0				\
+   : (C) == 'K' ? ((VALUE) & 0x3ff) == 0		\
+   : 0)
+
+/* Similar, but for floating constants, and defining letters G and H.
+   Here VALUE is the CONST_DOUBLE rtx itself.  */
+
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)	\
+  ((C) == 'G' ? fp_zero_operand (VALUE)			\
+   : (C) == 'H' ? arith_double_operand (VALUE, DImode)	\
+   : 0)
+
+/* Given an rtx X being reloaded into a reg required to be
+   in class CLASS, return the class of reg to actually use.
+   In general this is just CLASS; but on some machines
+   in some cases it is preferable to use a more restrictive class.  */
+/* We can't load constants into FP registers.  We can't load any FP constant
+   if an 'E' constraint fails to match it.  */
+#define PREFERRED_RELOAD_CLASS(X,CLASS)			\
+  (CONSTANT_P (X)					\
+   && (FP_REG_CLASS_P (CLASS)				\
+       || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT	\
+	   && (HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT	\
+	       || HOST_BITS_PER_INT != BITS_PER_WORD)))	\
+   ? NO_REGS : (CLASS))
+
+/* Return the register class of a scratch register needed to load IN into
+   a register of class CLASS in MODE.
+
+   On the SPARC, when PIC, we need a temporary when loading some addresses
+   into a register.
+
+   Also, we need a temporary when loading/storing a HImode/QImode value
+   between memory and the FPU registers.  This can happen when combine puts
+   a paradoxical subreg in a float/fix conversion insn.  */
+
+#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN)		\
+  ((FP_REG_CLASS_P (CLASS) && ((MODE) == HImode || (MODE) == QImode) \
+    && (GET_CODE (IN) == MEM					\
+	|| ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG)	\
+	    && true_regnum (IN) == -1))) ? GENERAL_REGS : NO_REGS)
+
+#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN)		\
+  ((FP_REG_CLASS_P (CLASS) && ((MODE) == HImode || (MODE) == QImode) \
+    && (GET_CODE (IN) == MEM					\
+	|| ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG)	\
+	    && true_regnum (IN) == -1))) ? GENERAL_REGS : NO_REGS)
+
+/* On SPARC it is not possible to directly move data between 
+   GENERAL_REGS and FP_REGS.  */
+#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
+  (FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2))
+
+/* Return the stack location to use for secondary memory needed reloads.
+   We want to use the reserved location just below the frame pointer.
+   However, we must ensure that there is a frame, so use assign_stack_local
+   if the frame size is zero.  */
+#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
+  (get_frame_size () == 0						\
+   ? assign_stack_local (MODE, GET_MODE_SIZE (MODE), 0)			\
+   : gen_rtx (MEM, MODE, gen_rtx (PLUS, Pmode, frame_pointer_rtx,	\
+				  GEN_INT (STARTING_FRAME_OFFSET))))
+
+/* Get_secondary_mem widens it's argument to BITS_PER_WORD which loses on v9
+   because the movsi and movsf patterns don't handle r/f moves.
+   For v8 we copy the default definition.  */
+#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \
+  (TARGET_V9							\
+   ? (GET_MODE_BITSIZE (MODE) < 32				\
+      ? mode_for_size (32, GET_MODE_CLASS (MODE), 0)		\
+      : MODE)							\
+   : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD			\
+      ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0)	\
+      : MODE))
+
+/* Return the maximum number of consecutive registers
+   needed to represent mode MODE in a register of class CLASS.  */
+/* On SPARC, this is the size of MODE in words.  */
+#define CLASS_MAX_NREGS(CLASS, MODE)	\
+  (FP_REG_CLASS_P (CLASS) ? (GET_MODE_SIZE (MODE) + 3) / 4 \
+   : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* Stack layout; function entry, exit and calling.  */
+
+/* Define the number of register that can hold parameters.
+   These two macros are used only in other macro definitions below.
+   MODE is the mode of the argument.
+   !v9: All args are passed in %o0-%o5.
+   v9: Non-float args are passed in %o0-5 and float args are passed in
+   %f0-%f15.  */
+#define NPARM_REGS(MODE) \
+  (TARGET_V9 ? (GET_MODE_CLASS (MODE) == MODE_FLOAT ? 16 : 6) : 6)
+
+/* Define this if pushing a word on the stack
+   makes the stack pointer a smaller address.  */
+#define STACK_GROWS_DOWNWARD
+
+/* Define this if the nominal address of the stack frame
+   is at the high-address end of the local variables;
+   that is, each additional local variable allocated
+   goes at a more negative offset in the frame.  */
+#define FRAME_GROWS_DOWNWARD
+
+/* Offset within stack frame to start allocating local variables at.
+   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
+   first local allocated.  Otherwise, it is the offset to the BEGINNING
+   of the first local allocated.  */
+/* This allows space for one TFmode floating point value.  */
+#define STARTING_FRAME_OFFSET \
+  (TARGET_V9 ? (SPARC_STACK_BIAS - 16) \
+   : (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)))
+
+/* If we generate an insn to push BYTES bytes,
+   this says how many the stack pointer really advances by.
+   On SPARC, don't define this because there are no push insns.  */
+/*  #define PUSH_ROUNDING(BYTES) */
+
+/* Offset of first parameter from the argument pointer register value.
+   !v9: This is 64 for the ins and locals, plus 4 for the struct-return reg
+   even if this function isn't going to use it.
+   v9: This is 128 for the ins and locals, plus a reserved space of 8.  */
+#define FIRST_PARM_OFFSET(FNDECL) \
+  (TARGET_V9 ? (SPARC_STACK_BIAS + 136) \
+   : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD))
+
+/* When a parameter is passed in a register, stack space is still
+   allocated for it.  */
+#ifndef SPARCV9
+#define REG_PARM_STACK_SPACE(DECL) (NPARM_REGS (SImode) * UNITS_PER_WORD)
+#endif
+
+/* Keep the stack pointer constant throughout the function.
+   This is both an optimization and a necessity: longjmp
+   doesn't behave itself when the stack pointer moves within
+   the function!  */
+#define ACCUMULATE_OUTGOING_ARGS
+
+/* Value is the number of bytes of arguments automatically
+   popped when returning from a subroutine call.
+   FUNDECL is the declaration node of the function (as a tree),
+   FUNTYPE is the data type of the function (as a tree),
+   or for a library call it is an identifier node for the subroutine name.
+   SIZE is the number of bytes of arguments passed on the stack.  */
+
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
+
+/* Some subroutine macros specific to this machine.
+   When !TARGET_FPU, put float return values in the general registers,
+   since we don't have any fp registers.  */
+#define BASE_RETURN_VALUE_REG(MODE) \
+  (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 8) \
+   : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 : 8))
+#define BASE_OUTGOING_VALUE_REG(MODE) \
+  (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 \
+		: TARGET_FRW ? 8 : 24) \
+   : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32	\
+      : (TARGET_FRW ? 8 : 24)))
+#define BASE_PASSING_ARG_REG(MODE) \
+  (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 8) \
+   : (8))
+#define BASE_INCOMING_ARG_REG(MODE) \
+  (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 \
+		: TARGET_FRW ? 8 : 24) \
+   : (TARGET_FRW ? 8 : 24))
+
+/* Define this macro if the target machine has "register windows".  This
+   C expression returns the register number as seen by the called function
+   corresponding to register number OUT as seen by the calling function.
+   Return OUT if register number OUT is not an outbound register.  */
+
+#define INCOMING_REGNO(OUT) \
+ ((TARGET_FRW || (OUT) < 8 || (OUT) > 15) ? (OUT) : (OUT) + 16)
+
+/* Define this macro if the target machine has "register windows".  This
+   C expression returns the register number as seen by the calling function
+   corresponding to register number IN as seen by the called function.
+   Return IN if register number IN is not an inbound register.  */
+
+#define OUTGOING_REGNO(IN) \
+ ((TARGET_FRW || (IN) < 24 || (IN) > 31) ? (IN) : (IN) - 16)
+
+/* Define how to find the value returned by a function.
+   VALTYPE is the data type of the value (as a tree).
+   If the precise function being called is known, FUNC is its FUNCTION_DECL;
+   otherwise, FUNC is 0.  */
+
+/* On SPARC the value is found in the first "output" register.  */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC)  \
+  gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE)))
+
+/* But the called function leaves it in the first "input" register.  */
+
+#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC)  \
+  gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_OUTGOING_VALUE_REG (TYPE_MODE (VALTYPE)))
+
+/* Define how to find the value returned by a library function
+   assuming the value has mode MODE.  */
+
+#define LIBCALL_VALUE(MODE)	\
+  gen_rtx (REG, MODE, BASE_RETURN_VALUE_REG (MODE))
+
+/* 1 if N is a possible register number for a function value
+   as seen by the caller.
+   On SPARC, the first "output" reg is used for integer values,
+   and the first floating point register is used for floating point values.  */
+
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 8 || (N) == 32)
+
+/* Define the size of space to allocate for the return value of an
+   untyped_call.  */
+
+#define APPLY_RESULT_SIZE 16
+
+/* 1 if N is a possible register number for function argument passing.
+   On SPARC, these are the "output" registers.  v9 also uses %f0-%f15.  */
+
+#define FUNCTION_ARG_REGNO_P(N) \
+  (TARGET_V9 ? (((N) < 14 && (N) > 7) || (N) > 31 && (N) < 48) \
+   : ((N) < 14 && (N) > 7))
+
+/* Define a data type for recording info about an argument list
+   during the scan of that argument list.  This data type should
+   hold all necessary information about the function itself
+   and about the args processed so far, enough to enable macros
+   such as FUNCTION_ARG to determine where the next arg should go.
+
+   On SPARC (!v9), this is a single integer, which is a number of words
+   of arguments scanned so far (including the invisible argument,
+   if any, which holds the structure-value-address).
+   Thus 7 or more means all following args should go on the stack.
+
+   For v9, we record how many of each type has been passed.  Different
+   types get passed differently.
+
+	- Float args are passed in %f0-15, after which they go to the stack
+	  where floats and doubles are passed 8 byte aligned and long doubles
+	  are passed 16 byte aligned.
+	- All aggregates are passed by reference.  The callee copies
+	  the structure if necessary, except if stdarg/varargs and the struct
+	  matches the ellipse in which case the caller makes a copy.
+	- Any non-float argument might be split between memory and reg %o5.
+	  ??? I don't think this can ever happen now that structs are no
+	  longer passed in regs.
+
+   For v9 return values:
+
+	- For all aggregates, the caller allocates space for the return value,
+          and passes the pointer as an implicit first argument, which is
+          allocated like all other arguments.
+	- The unimp instruction stuff for structure returns is gone.  */
+
+#ifdef SPARCV9
+enum sparc_arg_class { SPARC_ARG_INT = 0, SPARC_ARG_FLOAT = 1 };
+struct sparc_args {
+    int arg_count[2];	/* must be int! (for __builtin_args_info) */
+};
+#define CUMULATIVE_ARGS struct sparc_args
+
+/* Return index into CUMULATIVE_ARGS.  */
+
+#define GET_SPARC_ARG_CLASS(MODE) \
+  (GET_MODE_CLASS (MODE) == MODE_FLOAT ? SPARC_ARG_FLOAT : SPARC_ARG_INT)
+
+/* Round a register number up to a proper boundary for an arg of mode MODE.
+   This macro is only used in this file.
+
+   The "& (0x10000 - ...)" is used to round up to the next appropriate reg.  */
+
+#define ROUND_REG(CUM, MODE)				\
+  (GET_MODE_CLASS (MODE) != MODE_FLOAT			\
+   ? (CUM).arg_count[(int) GET_SPARC_ARG_CLASS (MODE)]	\
+   : ((CUM).arg_count[(int) GET_SPARC_ARG_CLASS (MODE)]	\
+      + GET_MODE_UNIT_SIZE (MODE) / 4 - 1)		\
+     & (0x10000 - GET_MODE_UNIT_SIZE (MODE) / 4))
+
+#define ROUND_ADVANCE(SIZE)	\
+  (((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+#else /* ! SPARCV9 */
+#define CUMULATIVE_ARGS int
+
+#define ROUND_REG(CUM, MODE) (CUM)
+
+#define ROUND_ADVANCE(SIZE)	\
+  ((SIZE + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+#endif /* ! SPARCV9 */
+
+/* Initialize a variable CUM of type CUMULATIVE_ARGS
+   for a call to a function whose data type is FNTYPE.
+   For a library call, FNTYPE is 0.
+
+   On SPARC, the offset always starts at 0: the first parm reg is always
+   the same reg.  */
+
+#ifdef SPARCV9
+extern int sparc_arg_count,sparc_n_named_args;
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME)		\
+  do {								\
+    (CUM).arg_count[(int) SPARC_ARG_INT] = 0;			\
+    (CUM).arg_count[(int) SPARC_ARG_FLOAT] = 0;			\
+    sparc_arg_count = 0;					\
+    sparc_n_named_args =					\
+      ((FNTYPE) && TYPE_ARG_TYPES (FNTYPE)			\
+       ? (list_length (TYPE_ARG_TYPES (FNTYPE))			\
+	  + (TREE_CODE (TREE_TYPE (FNTYPE)) == RECORD_TYPE	\
+	     || TREE_CODE (TREE_TYPE (FNTYPE)) == UNION_TYPE))	\
+       /* Can't tell, treat 'em all as named.  */		\
+       : 10000);						\
+  } while (0)
+#else
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) ((CUM) = 0)
+#endif
+
+/* Update the data in CUM to advance over an argument
+   of mode MODE and data type TYPE.
+   (TYPE is null for libcalls where that information may not be available.)  */
+
+#ifdef SPARCV9
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)		\
+  do {								\
+    (CUM).arg_count[(int) GET_SPARC_ARG_CLASS (MODE)] =		\
+      ROUND_REG ((CUM), (MODE))					\
+	+ (GET_MODE_CLASS (MODE) == MODE_FLOAT			\
+	   ? GET_MODE_SIZE (MODE) / 4				\
+	   : ROUND_ADVANCE ((MODE) == BLKmode			\
+			    ? GET_MODE_SIZE (Pmode)		\
+			    : GET_MODE_SIZE (MODE)));		\
+    sparc_arg_count++;						\
+  } while (0)
+#else
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)	\
+  ((CUM) += ((MODE) != BLKmode				\
+	     ? ROUND_ADVANCE (GET_MODE_SIZE (MODE))	\
+	     : ROUND_ADVANCE (int_size_in_bytes (TYPE))))
+#endif
+
+/* Return boolean indicating arg of mode MODE will be passed in a reg.
+   This macro is only used in this file.  */
+
+#ifdef SPARCV9
+#define PASS_IN_REG_P(CUM, MODE, TYPE)				\
+  (ROUND_REG ((CUM), (MODE)) < NPARM_REGS (MODE)		\
+   && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE)))		\
+   && ((TYPE)==0 || (MODE) != BLKmode))
+#else
+#define PASS_IN_REG_P(CUM, MODE, TYPE)				\
+  ((CUM) < NPARM_REGS (SImode)					\
+   && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE)))		\
+   && ((TYPE)==0 || (MODE) != BLKmode				\
+       || (TYPE_ALIGN (TYPE) % PARM_BOUNDARY == 0)))
+#endif
+
+/* Determine where to put an argument to a function.
+   Value is zero to push the argument on the stack,
+   or a hard register in which to store the argument.
+
+   MODE is the argument's machine mode.
+   TYPE is the data type of the argument (as a tree).
+    This is null for libcalls where that information may
+    not be available.
+   CUM is a variable of type CUMULATIVE_ARGS which gives info about
+    the preceding args and about the function being called.
+   NAMED is nonzero if this argument is a named parameter
+    (otherwise it is an extra parameter matching an ellipsis).  */
+
+/* On SPARC the first six args are normally in registers
+   and the rest are pushed.  Any arg that starts within the first 6 words
+   is at least partially passed in a register unless its data type forbids.
+   For v9, the first 6 int args are passed in regs and the first N
+   float args are passed in regs (where N is such that %f0-15 are filled).
+   The rest are pushed.  Any arg that starts within the first 6 words
+   is at least partially passed in a register unless its data type forbids.  */
+
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)				\
+  (PASS_IN_REG_P ((CUM), (MODE), (TYPE))				\
+   ? gen_rtx (REG, (MODE),						\
+	      (BASE_PASSING_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))))\
+   : 0)
+
+/* Define where a function finds its arguments.
+   This is different from FUNCTION_ARG because of register windows.  */
+
+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED)			\
+  (PASS_IN_REG_P ((CUM), (MODE), (TYPE))				\
+   ? gen_rtx (REG, (MODE),						\
+	      (BASE_INCOMING_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))))\
+   : 0)
+
+/* For an arg passed partly in registers and partly in memory,
+   this is the number of registers used.
+   For args passed entirely in registers or entirely in memory, zero.
+   Any arg that starts in the first 6 regs but won't entirely fit in them
+   needs partial registers on the Sparc (!v9).  On v9, there are no arguments
+   that are passed partially in registers (??? complex values?).  */
+
+#ifndef SPARCV9
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 		\
+  (PASS_IN_REG_P ((CUM), (MODE), (TYPE))				\
+   && ((CUM) + ((MODE) == BLKmode					\
+		? ROUND_ADVANCE (int_size_in_bytes (TYPE))		\
+		: ROUND_ADVANCE (GET_MODE_SIZE (MODE))) - NPARM_REGS (SImode) > 0)\
+   ? (NPARM_REGS (SImode) - (CUM))					\
+   : 0)
+#endif
+
+/* The SPARC ABI stipulates passing struct arguments (of any size) and
+   (!v9) quad-precision floats by invisible reference.
+   For Pascal, also pass arrays by reference.  */
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)		\
+  ((TYPE && (TREE_CODE (TYPE) == RECORD_TYPE				\
+	    || TREE_CODE (TYPE) == UNION_TYPE				\
+    	    || TREE_CODE (TYPE) == ARRAY_TYPE))				\
+   || (!TARGET_V9 && MODE == TFmode))
+
+/* A C expression that indicates when it is the called function's
+   responsibility to make copies of arguments passed by reference.
+   If the callee can determine that the argument won't be modified, it can
+   avoid the copy.  */
+/* ??? We'd love to be able to use NAMED here.  Unfortunately, it doesn't
+   include the last named argument so we keep track of the args ourselves.  */
+
+#ifdef SPARCV9
+#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
+  (sparc_arg_count < sparc_n_named_args)
+#endif
+
+/* Initialize data used by insn expanders.  This is called from
+   init_emit, once for each function, before code is generated.
+   For v9, clear the temp slot used by float/int DImode conversions.
+   ??? There is the 16 bytes at [%fp-16], however we'd like to delete this
+   space at some point.
+   ??? Use assign_stack_temp?  */
+
+extern void sparc64_init_expanders ();
+extern struct rtx_def *sparc64_fpconv_stack_temp ();
+#ifdef SPARCV9
+#define INIT_EXPANDERS sparc64_init_expanders ()
+#endif
+
+/* Define the information needed to generate branch and scc insns.  This is
+   stored from the compare operation.  Note that we can't use "rtx" here
+   since it hasn't been defined!  */
+
+extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1;
+
+/* Define the function that build the compare insn for scc and bcc.  */
+
+extern struct rtx_def *gen_compare_reg ();
+
+/* This function handles all v9 scc insns */
+
+extern int gen_v9_scc ();
+
+/* Generate the special assembly code needed to tell the assembler whatever
+   it might need to know about the return value of a function.
+
+   For Sparc assemblers, we need to output a .proc pseudo-op which conveys
+   information to the assembler relating to peephole optimization (done in
+   the assembler).  */
+
+#define ASM_DECLARE_RESULT(FILE, RESULT) \
+  fprintf ((FILE), "\t.proc\t0%o\n", sparc_type_code (TREE_TYPE (RESULT)))
+
+/* Output the label for a function definition.  */
+
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\
+do {									\
+  ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));			\
+  ASM_OUTPUT_LABEL (FILE, NAME);					\
+} while (0)
+
+/* This macro generates the assembly code for function entry.
+   FILE is a stdio stream to output the code to.
+   SIZE is an int: how many units of temporary storage to allocate.
+   Refer to the array `regs_ever_live' to determine which registers
+   to save; `regs_ever_live[I]' is nonzero if register number I
+   is ever used in the function.  This macro is responsible for
+   knowing which registers should not be saved even if used.  */
+
+/* On SPARC, move-double insns between fpu and cpu need an 8-byte block
+   of memory.  If any fpu reg is used in the function, we allocate
+   such a block here, at the bottom of the frame, just in case it's needed.
+
+   If this function is a leaf procedure, then we may choose not
+   to do a "save" insn.  The decision about whether or not
+   to do this is made in regclass.c.  */
+
+extern int leaf_function;
+#define FUNCTION_PROLOGUE(FILE, SIZE)				\
+  (TARGET_FRW ? sparc_flat_output_function_prologue (FILE, SIZE) \
+   : output_function_prologue (FILE, SIZE, leaf_function))
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+   for profiling a function entry.  */
+
+#define FUNCTION_PROFILER(FILE, LABELNO)  			\
+  do {								\
+    fputs ("\tsethi %hi(", (FILE));				\
+    ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO);		\
+    fputs ("),%o0\n", (FILE));					\
+    if (TARGET_MEDANY)						\
+      fprintf (FILE, "\tadd %%o0,%s,%%o0\n",			\
+	       MEDANY_BASE_REG);				\
+    fputs ("\tcall mcount\n\tadd %lo(", (FILE));		\
+    ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO);		\
+    fputs ("),%o0,%o0\n", (FILE));				\
+  } while (0)
+
+/* Output assembler code to FILE to initialize this source file's
+   basic block profiling info, if that has not already been done.  */
+
+#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO)  \
+  do { \
+    if (TARGET_MEDANY) \
+      fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tor %%0,%%lo(LPBX0),%%o0\n\tld [%s+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%s,%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n", \
+	       MEDANY_BASE_REG, (LABELNO), MEDANY_BASE_REG, (LABELNO)); \
+    else \
+      fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tld [%%lo(LPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%%lo(LPBX0),%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n", \
+	       (LABELNO), (LABELNO)); \
+  } while (0)
+
+/* Output assembler code to FILE to increment the entry-count for
+   the BLOCKNO'th basic block in this source file.  */
+
+#define BLOCK_PROFILER(FILE, BLOCKNO) \
+{ \
+  int blockn = (BLOCKNO); \
+  if (TARGET_MEDANY) \
+    fprintf (FILE, "\tsethi %%hi(LPBX2+%d),%%g1\n\tor %%g1,%%lo(LPBX2+%d),%%g1\n\tld [%%g1+%s],%%g2\n\tadd %%g2,1,%%g2\n\tst %%g2,[%%g1+%s]\n", \
+	     4 * blockn, 4 * blockn, MEDANY_BASE_REG, MEDANY_BASE_REG); \
+  else \
+    fprintf (FILE, "\tsethi %%hi(LPBX2+%d),%%g1\n\tld [%%lo(LPBX2+%d)+%%g1],%%g2\n\
+\tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(LPBX2+%d)+%%g1]\n", \
+	     4 * blockn, 4 * blockn, 4 * blockn); \
+}
+
+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
+   the stack pointer does not matter.  The value is tested only in
+   functions that have frame pointers.
+   No definition is equivalent to always zero.  */
+
+extern int current_function_calls_alloca;
+extern int current_function_outgoing_args_size;
+
+#define EXIT_IGNORE_STACK	\
+ (get_frame_size () != 0	\
+  || current_function_calls_alloca || current_function_outgoing_args_size)
+
+/* This macro generates the assembly code for function exit,
+   on machines that need it.  If FUNCTION_EPILOGUE is not defined
+   then individual return instructions are generated for each
+   return statement.  Args are same as for FUNCTION_PROLOGUE.
+
+   The function epilogue should not depend on the current stack pointer!
+   It should use the frame pointer only.  This is mandatory because
+   of alloca; we also take advantage of it to omit stack adjustments
+   before returning.  */
+
+/* This declaration is needed due to traditional/ANSI
+   incompatibilities which cannot be #ifdefed away
+   because they occur inside of macros.  Sigh.  */
+extern union tree_node *current_function_decl;
+
+#define FUNCTION_EPILOGUE(FILE, SIZE)				\
+  (TARGET_FRW ? sparc_flat_output_function_epilogue (FILE, SIZE) \
+   : output_function_epilogue (FILE, SIZE, leaf_function))
+
+#define DELAY_SLOTS_FOR_EPILOGUE	\
+  (TARGET_FRW ? sparc_flat_epilogue_delay_slots () : 1)
+#define ELIGIBLE_FOR_EPILOGUE_DELAY(trial, slots_filled)	\
+  (TARGET_FRW ? sparc_flat_eligible_for_epilogue_delay (trial, slots_filled) \
+   : eligible_for_epilogue_delay (trial, slots_filled))
+
+/* Output assembler code for a block containing the constant parts
+   of a trampoline, leaving space for the variable parts.  */
+
+/* On the sparc, the trampoline contains five instructions:
+     sethi #TOP_OF_FUNCTION,%g1
+     or #BOTTOM_OF_FUNCTION,%g1,%g1
+     sethi #TOP_OF_STATIC,%g2
+     jmp g1
+     or #BOTTOM_OF_STATIC,%g2,%g2  */
+#define TRAMPOLINE_TEMPLATE(FILE)					\
+{									\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x81C04000));	\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\
+}
+
+/* Length in units of the trampoline for entering a nested function.  */
+
+#define TRAMPOLINE_SIZE 20
+
+/* Emit RTL insns to initialize the variable parts of a trampoline.
+   FNADDR is an RTX for the address of the function's pure code.
+   CXT is an RTX for the static chain value for the function.  */
+
+void sparc_initialize_trampoline ();
+void sparc64_initialize_trampoline ();
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+  do {								\
+    if (TARGET_V9)						\
+      sparc64_initialize_trampoline (TRAMP, FNADDR, CXT);	\
+    else							\
+      sparc_initialize_trampoline (TRAMP, FNADDR, CXT);		\
+  } while (0)
+
+/* Generate necessary RTL for __builtin_saveregs().
+   ARGLIST is the argument list; see expr.c.  */
+extern struct rtx_def *sparc_builtin_saveregs ();
+#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) sparc_builtin_saveregs (ARGLIST)
+
+/* Generate RTL to flush the register windows so as to make arbitrary frames
+   available.  */
+#define SETUP_FRAME_ADDRESSES()		\
+  emit_insn (gen_flush_register_windows ())
+
+/* Given an rtx for the address of a frame,
+   return an rtx for the address of the word in the frame
+   that holds the dynamic chain--the previous frame's address.
+   ??? -mflat support? */
+#define DYNAMIC_CHAIN_ADDRESS(frame) \
+  gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 14 * UNITS_PER_WORD))
+
+/* The return address isn't on the stack, it is in a register, so we can't
+   access it from the current frame pointer.  We can access it from the
+   previous frame pointer though by reading a value from the register window
+   save area.  */
+#define RETURN_ADDR_IN_PREVIOUS_FRAME
+
+/* The current return address is in %i7.  The return address of anything
+   farther back is in the register window save area at [%fp+60].  */
+/* ??? This ignores the fact that the actual return address is +8 for normal
+   returns, and +12 for structure returns.  */
+#define RETURN_ADDR_RTX(count, frame)		\
+  ((count == -1)				\
+   ? gen_rtx (REG, Pmode, 31)			\
+   : copy_to_reg (gen_rtx (MEM, Pmode,		\
+			   memory_address (Pmode, plus_constant (frame, 15 * UNITS_PER_WORD)))))
+
+/* Addressing modes, and classification of registers for them.  */
+
+/* #define HAVE_POST_INCREMENT */
+/* #define HAVE_POST_DECREMENT */
+
+/* #define HAVE_PRE_DECREMENT */
+/* #define HAVE_PRE_INCREMENT */
+
+/* Macros to check register numbers against specific register classes.  */
+
+/* These assume that REGNO is a hard or pseudo reg number.
+   They give nonzero only if REGNO is a hard reg of the suitable class
+   or a pseudo reg currently allocated to a suitable hard reg.
+   Since they use reg_renumber, they are safe only once reg_renumber
+   has been allocated, which happens in local-alloc.c.  */
+
+#define REGNO_OK_FOR_INDEX_P(REGNO) \
+(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0)
+#define REGNO_OK_FOR_BASE_P(REGNO) \
+(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0)
+#define REGNO_OK_FOR_FP_P(REGNO) \
+  (((unsigned) (REGNO) - 32 < (TARGET_V9 ? 64 : 32)) \
+   || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? 64 : 32)))
+#define REGNO_OK_FOR_CCFP_P(REGNO) \
+ (TARGET_V9 \
+  && ((unsigned) (REGNO) - 96 < 4) || ((unsigned) reg_renumber[REGNO] - 96 < 4))
+
+/* Now macros that check whether X is a register and also,
+   strictly, whether it is in a specified class.
+
+   These macros are specific to the SPARC, and may be used only
+   in code for printing assembler insns and in conditions for
+   define_optimization.  */
+
+/* 1 if X is an fp register.  */
+
+#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))
+
+/* Maximum number of registers that can appear in a valid memory address.  */
+
+#define MAX_REGS_PER_ADDRESS 2
+
+/* Recognize any constant value that is a valid address.
+   When PIC, we do not accept an address that would require a scratch reg
+   to load into a register.  */
+
+#define CONSTANT_ADDRESS_P(X)   \
+  (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF		\
+   || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH			\
+   || (GET_CODE (X) == CONST						\
+       && ! (flag_pic && pic_address_needs_scratch (X))))
+
+/* Define this, so that when PIC, reload won't try to reload invalid
+   addresses which require two reload registers.  */
+
+#define LEGITIMATE_PIC_OPERAND_P(X)  (! pic_address_needs_scratch (X))
+
+/* Nonzero if the constant value X is a legitimate general operand.
+   Anything can be made to work except floating point constants.  */
+
+#define LEGITIMATE_CONSTANT_P(X) \
+  (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode)
+
+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
+   and check its validity for a certain class.
+   We have two alternate definitions for each of them.
+   The usual definition accepts all pseudo regs; the other rejects
+   them unless they have been allocated suitable hard regs.
+   The symbol REG_OK_STRICT causes the latter definition to be used.
+
+   Most source files want to accept pseudo regs in the hope that
+   they will get allocated to the class that the insn wants them to be in.
+   Source files for reload pass need to be strict.
+   After reload, it makes no difference, since pseudo regs have
+   been eliminated by then.  */
+
+/* Optional extra constraints for this machine.  Borrowed from romp.h.
+
+   For the SPARC, `Q' means that this is a memory operand but not a
+   symbolic memory operand.  Note that an unassigned pseudo register
+   is such a memory operand.  Needed because reload will generate
+   these things in insns and then not re-recognize the insns, causing
+   constrain_operands to fail.
+
+   `S' handles constraints for calls.  ??? So where is it?  */
+
+#ifndef REG_OK_STRICT
+
+/* Nonzero if X is a hard reg that can be used as an index
+   or if it is a pseudo reg.  */
+#define REG_OK_FOR_INDEX_P(X) \
+  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32) && REGNO (X) != 0)
+/* Nonzero if X is a hard reg that can be used as a base reg
+   or if it is a pseudo reg.  */
+#define REG_OK_FOR_BASE_P(X) \
+  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32) && REGNO (X) != 0)
+
+/* 'T', 'U' are for aligned memory loads which aren't needed for v9.  */
+
+#define EXTRA_CONSTRAINT(OP, C)				\
+  ((C) == 'Q'						\
+   ? ((GET_CODE (OP) == MEM				\
+       && memory_address_p (GET_MODE (OP), XEXP (OP, 0)) \
+       && ! symbolic_memory_operand (OP, VOIDmode))	\
+      || (reload_in_progress && GET_CODE (OP) == REG	\
+	  && REGNO (OP) >= FIRST_PSEUDO_REGISTER))	\
+   : ! TARGET_V9 && (C) == 'T'			\
+   ? (mem_aligned_8 (OP))				\
+   : ! TARGET_V9 && (C) == 'U'						\
+   ? (register_ok_for_ldd (OP))				\
+   : 0)
+ 
+#else
+
+/* Nonzero if X is a hard reg that can be used as an index.  */
+#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+/* Nonzero if X is a hard reg that can be used as a base reg.  */
+#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+
+#define EXTRA_CONSTRAINT(OP, C)				\
+  ((C) == 'Q'						\
+   ? (GET_CODE (OP) == REG				\
+      ? (REGNO (OP) >= FIRST_PSEUDO_REGISTER		\
+	 && reg_renumber[REGNO (OP)] < 0)		\
+      : GET_CODE (OP) == MEM)				\
+   : ! TARGET_V9 && (C) == 'T'			\
+   ? mem_aligned_8 (OP) && strict_memory_address_p (Pmode, XEXP (OP, 0)) \
+   : ! TARGET_V9 && (C) == 'U'			\
+   ? (GET_CODE (OP) == REG				\
+      && (REGNO (OP) < FIRST_PSEUDO_REGISTER		\
+	  || reg_renumber[REGNO (OP)] > 0)		\
+      && register_ok_for_ldd (OP)) : 0)
+#endif
+
+/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
+   that is a valid memory address for an instruction.
+   The MODE argument is the machine mode for the MEM expression
+   that wants to use this address.
+
+   On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT
+   ordinarily.  This changes a bit when generating PIC.
+
+   If you change this, execute "rm explow.o recog.o reload.o".  */
+
+#define RTX_OK_FOR_BASE_P(X)						\
+  ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))			\
+  || (GET_CODE (X) == SUBREG						\
+      && GET_CODE (SUBREG_REG (X)) == REG				\
+      && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
+
+#define RTX_OK_FOR_INDEX_P(X)						\
+  ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))			\
+  || (GET_CODE (X) == SUBREG						\
+      && GET_CODE (SUBREG_REG (X)) == REG				\
+      && REG_OK_FOR_INDEX_P (SUBREG_REG (X))))
+
+#define RTX_OK_FOR_OFFSET_P(X)						\
+  (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000)
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)		\
+{ if (RTX_OK_FOR_BASE_P (X))				\
+    goto ADDR;						\
+  else if (GET_CODE (X) == PLUS)			\
+    {							\
+      register rtx op0 = XEXP (X, 0);			\
+      register rtx op1 = XEXP (X, 1);			\
+      if (flag_pic && op0 == pic_offset_table_rtx)	\
+	{						\
+	  if (RTX_OK_FOR_BASE_P (op1))			\
+	    goto ADDR;					\
+	  else if (flag_pic == 1			\
+		   && GET_CODE (op1) != REG		\
+		   && GET_CODE (op1) != LO_SUM		\
+		   && GET_CODE (op1) != MEM		\
+		   && (GET_CODE (op1) != CONST_INT	\
+		       || SMALL_INT (op1)))		\
+	    goto ADDR;					\
+	}						\
+      else if (RTX_OK_FOR_BASE_P (op0))			\
+	{						\
+	  if (RTX_OK_FOR_INDEX_P (op1)			\
+	      || RTX_OK_FOR_OFFSET_P (op1))		\
+	    goto ADDR;					\
+	}						\
+      else if (RTX_OK_FOR_BASE_P (op1))			\
+	{						\
+	  if (RTX_OK_FOR_INDEX_P (op0)			\
+	      || RTX_OK_FOR_OFFSET_P (op0))		\
+	    goto ADDR;					\
+	}						\
+    }							\
+  else if (GET_CODE (X) == LO_SUM)			\
+    {							\
+      register rtx op0 = XEXP (X, 0);			\
+      register rtx op1 = XEXP (X, 1);			\
+      if (RTX_OK_FOR_BASE_P (op0)			\
+	  && CONSTANT_P (op1)				\
+	  /* We can't allow TFmode, because an offset	\
+	     greater than or equal to the alignment (8)	\
+	     may cause the LO_SUM to overflow.  */	\
+	  && MODE != TFmode)				\
+	goto ADDR;					\
+    }							\
+  else if (GET_CODE (X) == CONST_INT && SMALL_INT (X))	\
+    goto ADDR;						\
+}
+
+/* Try machine-dependent ways of modifying an illegitimate address
+   to be legitimate.  If we find one, return the new, valid address.
+   This macro is used in only one place: `memory_address' in explow.c.
+
+   OLDX is the address as it was before break_out_memory_refs was called.
+   In some cases it is useful to look at this to decide what needs to be done.
+
+   MODE and WIN are passed so that this macro can use
+   GO_IF_LEGITIMATE_ADDRESS.
+
+   It is always safe for this macro to do nothing.  It exists to recognize
+   opportunities to optimize the output.  */
+
+/* On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG.  */
+extern struct rtx_def *legitimize_pic_address ();
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)	\
+{ rtx sparc_x = (X);						\
+  if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT)	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 1),			\
+		   force_operand (XEXP (X, 0), NULL_RTX));	\
+  if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT)	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0),			\
+		   force_operand (XEXP (X, 1), NULL_RTX));	\
+  if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == PLUS)	\
+    (X) = gen_rtx (PLUS, Pmode, force_operand (XEXP (X, 0), NULL_RTX),\
+		   XEXP (X, 1));				\
+  if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == PLUS)	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0),			\
+		   force_operand (XEXP (X, 1), NULL_RTX));	\
+  if (sparc_x != (X) && memory_address_p (MODE, X))		\
+    goto WIN;							\
+  if (flag_pic) (X) = legitimize_pic_address (X, MODE, 0);	\
+  else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1)))	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0),			\
+		   copy_to_mode_reg (Pmode, XEXP (X, 1)));	\
+  else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0)))	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 1),			\
+		   copy_to_mode_reg (Pmode, XEXP (X, 0)));	\
+  else if (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST	\
+	   || GET_CODE (X) == LABEL_REF)			\
+    (X) = gen_rtx (LO_SUM, Pmode,				\
+		   copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, X)), X); \
+  if (memory_address_p (MODE, X))				\
+    goto WIN; }
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+   has an effect that depends on the machine mode it is used for.
+   On the SPARC this is never true.  */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
+
+/* If we are referencing a function make the SYMBOL_REF special.
+   In the Medium/Anywhere code model, %g4 points to the data segment so we
+   must not add it to function addresses.  */
+
+#define ENCODE_SECTION_INFO(DECL) \
+  do {							\
+    if (TARGET_MEDANY && TREE_CODE (DECL) == FUNCTION_DECL) \
+      SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;	\
+  } while (0)
+
+/* Specify the machine mode that this machine uses
+   for the index in the tablejump instruction.  */
+#define CASE_VECTOR_MODE Pmode
+
+/* Define this if the tablejump instruction expects the table
+   to contain offsets from the address of the table.
+   Do not define this if the table should contain absolute addresses.  */
+/* #define CASE_VECTOR_PC_RELATIVE */
+
+/* Specify the tree operation to be used to convert reals to integers.  */
+#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+
+/* This is the kind of divide that is easiest to do in the general case.  */
+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
+
+/* Define this as 1 if `char' should by default be signed; else as 0.  */
+#define DEFAULT_SIGNED_CHAR 1
+
+/* Max number of bytes we can move from memory to memory
+   in one reasonably fast instruction.  */
+#define MOVE_MAX 8
+
+#if 0 /* Sun 4 has matherr, so this is no good.  */
+/* This is the value of the error code EDOM for this machine,
+   used by the sqrt instruction.  */
+#define TARGET_EDOM 33
+
+/* This is how to refer to the variable errno.  */
+#define GEN_ERRNO_RTX \
+  gen_rtx (MEM, SImode, gen_rtx (SYMBOL_REF, Pmode, "errno"))
+#endif /* 0 */
+
+/* Define if operations between registers always perform the operation
+   on the full register even if a narrower mode is specified.  */
+#define WORD_REGISTER_OPERATIONS
+
+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
+   will either zero-extend or sign-extend.  The value of this macro should
+   be the code that says which one of the two operations is implicitly
+   done, NIL if none.  */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* Nonzero if access to memory by bytes is slow and undesirable.
+   For RISC chips, it means that access to memory by bytes is no
+   better than access by words when possible, so grab a whole word
+   and maybe make use of that.  */
+#define SLOW_BYTE_ACCESS 1
+
+/* We assume that the store-condition-codes instructions store 0 for false
+   and some other value for true.  This is the value stored for true.  */
+
+#define STORE_FLAG_VALUE 1
+
+/* When a prototype says `char' or `short', really pass an `int'.  */
+#define PROMOTE_PROTOTYPES
+
+/* Define this to be nonzero if shift instructions ignore all but the low-order
+   few bits. */
+#define SHIFT_COUNT_TRUNCATED 1
+
+/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
+   is done just by pretending it is already truncated.  */
+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+
+/* Specify the machine mode that pointers have.
+   After generation of rtl, the compiler makes no further distinction
+   between pointers and any other objects of this machine mode.  */
+#define Pmode (TARGET_PTR64 ? DImode : SImode)
+
+/* Generate calls to memcpy, memcmp and memset.  */
+#define TARGET_MEM_FUNCTIONS
+
+/* Add any extra modes needed to represent the condition code.
+
+   On the Sparc, we have a "no-overflow" mode which is used when an add or
+   subtract insn is used to set the condition code.  Different branches are
+   used in this case for some operations.
+
+   We also have two modes to indicate that the relevant condition code is
+   in the floating-point condition code register.  One for comparisons which
+   will generate an exception if the result is unordered (CCFPEmode) and
+   one for comparisons which will never trap (CCFPmode).  This really should
+   be a separate register, but we don't want to go to 65 registers.
+
+   CCXmode and CCX_NOOVmode are only used by v9.  */
+
+#define EXTRA_CC_MODES CCXmode, CC_NOOVmode, CCX_NOOVmode, CCFPmode, CCFPEmode
+
+/* Define the names for the modes specified above.  */
+
+#define EXTRA_CC_NAMES "CCX", "CC_NOOV", "CCX_NOOV", "CCFP", "CCFPE"
+
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
+   return the mode to be used for the comparison.  For floating-point,
+   CCFP[E]mode is used.  CC_NOOVmode should be used when the first operand is a
+   PLUS, MINUS, NEG, or ASHIFT.  CCmode should be used when no special
+   processing is needed.  */
+#define SELECT_CC_MODE(OP,X,Y) \
+  (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT				\
+   ? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode)			\
+   : ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS			\
+       || GET_CODE (X) == NEG || GET_CODE (X) == ASHIFT)		\
+      ? (TARGET_V9 && GET_MODE (X) == DImode ? CCX_NOOVmode : CC_NOOVmode) \
+      : (TARGET_V9 && GET_MODE (X) == DImode ? CCXmode : CCmode)))
+
+/* Return non-zero if SELECT_CC_MODE will never return MODE for a
+   floating point inequality comparison.  */
+
+#define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode)
+
+/* A function address in a call instruction
+   is a byte address (for indexing purposes)
+   so give the MEM rtx a byte's mode.  */
+#define FUNCTION_MODE SImode
+
+/* Define this if addresses of constant functions
+   shouldn't be put through pseudo regs where they can be cse'd.
+   Desirable on machines where ordinary constants are expensive
+   but a CALL with constant address is cheap.  */
+#define NO_FUNCTION_CSE
+
+/* alloca should avoid clobbering the old register save area.  */
+#define SETJMP_VIA_SAVE_AREA
+
+/* Define subroutines to call to handle multiply and divide.
+   Use the subroutines that Sun's library provides.
+   The `*' prevents an underscore from being prepended by the compiler.  */
+
+#define DIVSI3_LIBCALL "*.div"
+#define UDIVSI3_LIBCALL "*.udiv"
+#define MODSI3_LIBCALL "*.rem"
+#define UMODSI3_LIBCALL "*.urem"
+/* .umul is a little faster than .mul.  */
+#define MULSI3_LIBCALL "*.umul"
+
+/* Define library calls for quad FP operations.  These are all part of the
+   SPARC ABI.  */
+#define ADDTF3_LIBCALL "_Q_add"
+#define SUBTF3_LIBCALL "_Q_sub"
+#define NEGTF2_LIBCALL "_Q_neg"
+#define MULTF3_LIBCALL "_Q_mul"
+#define DIVTF3_LIBCALL "_Q_div"
+#define FLOATSITF2_LIBCALL "_Q_itoq"
+#define FIX_TRUNCTFSI2_LIBCALL "_Q_qtoi"
+#define FIXUNS_TRUNCTFSI2_LIBCALL "_Q_qtou"
+#define EXTENDSFTF2_LIBCALL "_Q_stoq"
+#define TRUNCTFSF2_LIBCALL "_Q_qtos"
+#define EXTENDDFTF2_LIBCALL "_Q_dtoq"
+#define TRUNCTFDF2_LIBCALL "_Q_qtod"
+#define EQTF2_LIBCALL "_Q_feq"
+#define NETF2_LIBCALL "_Q_fne"
+#define GTTF2_LIBCALL "_Q_fgt"
+#define GETF2_LIBCALL "_Q_fge"
+#define LTTF2_LIBCALL "_Q_flt"
+#define LETF2_LIBCALL "_Q_fle"
+
+/* We can define the TFmode sqrt optab only if TARGET_FPU.  This is because
+   with soft-float, the SFmode and DFmode sqrt instructions will be absent,
+   and the compiler will notice and try to use the TFmode sqrt instruction
+   for calls to the builtin function sqrt, but this fails.  */
+#define INIT_TARGET_OPTABS						\
+  do {									\
+    add_optab->handlers[(int) TFmode].libfunc				\
+      = gen_rtx (SYMBOL_REF, Pmode, ADDTF3_LIBCALL);			\
+    sub_optab->handlers[(int) TFmode].libfunc				\
+      = gen_rtx (SYMBOL_REF, Pmode, SUBTF3_LIBCALL);			\
+    neg_optab->handlers[(int) TFmode].libfunc				\
+      = gen_rtx (SYMBOL_REF, Pmode, NEGTF2_LIBCALL);			\
+    smul_optab->handlers[(int) TFmode].libfunc				\
+      = gen_rtx (SYMBOL_REF, Pmode, MULTF3_LIBCALL);			\
+    flodiv_optab->handlers[(int) TFmode].libfunc			\
+      = gen_rtx (SYMBOL_REF, Pmode, DIVTF3_LIBCALL);			\
+    eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EQTF2_LIBCALL);		\
+    netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, NETF2_LIBCALL);		\
+    gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GTTF2_LIBCALL);		\
+    getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GETF2_LIBCALL);		\
+    lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LTTF2_LIBCALL);		\
+    letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LETF2_LIBCALL);		\
+    trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFSF2_LIBCALL);   \
+    trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFDF2_LIBCALL);   \
+    extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDSFTF2_LIBCALL); \
+    extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDDFTF2_LIBCALL); \
+    floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, FLOATSITF2_LIBCALL);    \
+    fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIX_TRUNCTFSI2_LIBCALL);  \
+    fixunstfsi_libfunc							\
+      = gen_rtx (SYMBOL_REF, Pmode, FIXUNS_TRUNCTFSI2_LIBCALL);		\
+    if (TARGET_FPU)							\
+      sqrt_optab->handlers[(int) TFmode].libfunc			\
+	= gen_rtx (SYMBOL_REF, Pmode, "_Q_sqrt");			\
+    INIT_SUBTARGET_OPTABS;						\
+  } while (0)
+
+/* This is meant to be redefined in the host dependent files */
+#define INIT_SUBTARGET_OPTABS
+
+/* Compute the cost of computing a constant rtl expression RTX
+   whose rtx-code is CODE.  The body of this macro is a portion
+   of a switch statement.  If the code is computed here,
+   return it with a return statement.  Otherwise, break from the switch.  */
+
+#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
+  case CONST_INT:						\
+    if (INTVAL (RTX) < 0x1000 && INTVAL (RTX) >= -0x1000)	\
+      return 0;							\
+  case HIGH:							\
+    return 2;							\
+  case CONST:							\
+  case LABEL_REF:						\
+  case SYMBOL_REF:						\
+    return 4;							\
+  case CONST_DOUBLE:						\
+    if (GET_MODE (RTX) == DImode)				\
+      if ((XINT (RTX, 3) == 0					\
+	   && (unsigned) XINT (RTX, 2) < 0x1000)		\
+	  || (XINT (RTX, 3) == -1				\
+	      && XINT (RTX, 2) < 0				\
+	      && XINT (RTX, 2) >= -0x1000))			\
+	return 0;						\
+    return 8;
+
+/* Compute the cost of an address.  For the sparc, all valid addresses are
+   the same cost.
+   ??? Is this true for v9?  */
+
+#define ADDRESS_COST(RTX)  1
+
+/* Compute extra cost of moving data between one register class
+   and another.
+   ??? v9: We ignore FPCC_REGS on the assumption they'll never be seen.  */
+#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
+  (((FP_REG_CLASS_P (CLASS1) && (CLASS2) == GENERAL_REGS) \
+    || ((CLASS1) == GENERAL_REGS && FP_REG_CLASS_P (CLASS2))) ? 6 : 2)
+
+/* Provide the costs of a rtl expression.  This is in the body of a
+   switch on CODE.  The purpose for the cost of MULT is to encourage
+   `synth_mult' to find a synthetic multiply when reasonable.
+
+   If we need more than 12 insns to do a multiply, then go out-of-line,
+   since the call overhead will be < 10% of the cost of the multiply.  */
+
+#define RTX_COSTS(X,CODE,OUTER_CODE)			\
+  case MULT:						\
+    return (TARGET_V8 || TARGET_V9) ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25);	\
+  case DIV:						\
+  case UDIV:						\
+  case MOD:						\
+  case UMOD:						\
+    return COSTS_N_INSNS (25);				\
+  /* Make FLOAT and FIX more expensive than CONST_DOUBLE,\
+     so that cse will favor the latter.  */		\
+  case FLOAT:						\
+  case FIX:						\
+    return 19;
+
+/* Adjust the cost of dependencies.  */
+#define ADJUST_COST(INSN,LINK,DEP,COST) \
+  if (TARGET_SUPERSPARC) \
+  (COST) = supersparc_adjust_cost (INSN, LINK, DEP, COST)
+
+/* Conditional branches with empty delay slots have a length of two.  */
+#define ADJUST_INSN_LENGTH(INSN, LENGTH)	\
+  if (GET_CODE (INSN) == CALL_INSN					\
+      || (GET_CODE (INSN) == JUMP_INSN && ! simplejump_p (insn)))	\
+    LENGTH += 1;
+
+/* Control the assembler format that we output.  */
+
+/* Output at beginning of assembler file.  */
+
+#define ASM_FILE_START(file)
+
+/* Output to assembler file text saying following lines
+   may contain character constants, extra white space, comments, etc.  */
+
+#define ASM_APP_ON ""
+
+/* Output to assembler file text saying following lines
+   no longer contain unusual constructs.  */
+
+#define ASM_APP_OFF ""
+
+/* ??? Try to make the style consistent here (_OP?).  */
+
+#define ASM_LONGLONG	".xword"
+#define ASM_LONG	".word"
+#define ASM_SHORT	".half"
+#define ASM_BYTE_OP	".byte"
+#define ASM_FLOAT	".single"
+#define ASM_DOUBLE	".double"
+#define ASM_LONGDOUBLE	".xxx"		/* ??? Not known (or used yet). */
+
+/* Output before read-only data.  */
+
+#define TEXT_SECTION_ASM_OP ".text"
+
+/* Output before writable data.  */
+
+#define DATA_SECTION_ASM_OP ".data"
+
+/* How to refer to registers in assembler output.
+   This sequence is indexed by compiler's hard-register-number (see above).  */
+
+#ifdef SPARCV9
+#define REGISTER_NAMES \
+{"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",		\
+ "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",		\
+ "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",		\
+ "%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",		\
+ "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",		\
+ "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",		\
+ "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",	\
+ "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",	\
+ "%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",	\
+ "%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",	\
+ "%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",	\
+ "%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",	\
+ "%fcc0", "%fcc1", "%fcc2", "%fcc3"}
+#else
+#define REGISTER_NAMES \
+{"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",		\
+ "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",		\
+ "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",		\
+ "%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",		\
+ "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",		\
+ "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",		\
+ "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",	\
+ "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31"}
+#endif
+
+/* Define additional names for use in asm clobbers and asm declarations.
+
+   We define the fake Condition Code register as an alias for reg 0 (which
+   is our `condition code' register), so that condition codes can easily
+   be clobbered by an asm.  No such register actually exists.  Condition
+   codes are partly stored in the PSR and partly in the FSR.  */
+
+#define ADDITIONAL_REGISTER_NAMES	{"ccr", 0, "cc", 0}
+
+/* How to renumber registers for dbx and gdb.  */
+
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+/* On Sun 4, this limit is 2048.  We use 1500 to be safe,
+   since the length can run past this up to a continuation point.  */
+#define DBX_CONTIN_LENGTH 1500
+
+/* This is how to output a note to DBX telling it the line number
+   to which the following sequence of instructions corresponds.
+
+   This is needed for SunOS 4.0, and should not hurt for 3.2
+   versions either.  */
+#define ASM_OUTPUT_SOURCE_LINE(file, line)		\
+  { static int sym_lineno = 1;				\
+    fprintf (file, ".stabn 68,0,%d,LM%d\nLM%d:\n",	\
+	     line, sym_lineno, sym_lineno);		\
+    sym_lineno += 1; }
+
+/* This is how to output the definition of a user-level label named NAME,
+   such as the label on a static function or variable NAME.  */
+
+#define ASM_OUTPUT_LABEL(FILE,NAME)	\
+  do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
+
+/* This is how to output a command to make the user-level label named NAME
+   defined for reference from other files.  */
+
+#define ASM_GLOBALIZE_LABEL(FILE,NAME)	\
+  do { fputs ("\t.global ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+
+/* This is how to output a reference to a user-level label named NAME.
+   `assemble_name' uses this.  */
+
+#define ASM_OUTPUT_LABELREF(FILE,NAME)	\
+  fprintf (FILE, "_%s", NAME)
+
+/* This is how to output a definition of an internal numbered label where
+   PREFIX is the class of label and NUM is the number within the class.  */
+
+#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)	\
+  fprintf (FILE, "%s%d:\n", PREFIX, NUM)
+
+/* This is how to output a reference to an internal numbered label where
+   PREFIX is the class of label and NUM is the number within the class.  */
+/* FIXME:  This should be used throughout gcc, and documented in the texinfo
+   files.  There is no reason you should have to allocate a buffer and
+   `sprintf' to reference an internal label (as opposed to defining it).  */
+
+#define ASM_OUTPUT_INTERNAL_LABELREF(FILE,PREFIX,NUM)	\
+  fprintf (FILE, "%s%d", PREFIX, NUM)
+
+/* This is how to store into the string LABEL
+   the symbol_ref name of an internal numbered label where
+   PREFIX is the class of label and NUM is the number within the class.
+   This is suitable for output with `assemble_name'.  */
+
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
+  sprintf (LABEL, "*%s%d", PREFIX, NUM)
+
+/* This is how to output an assembler line defining a `double' constant.  */
+
+#define ASM_OUTPUT_DOUBLE(FILE,VALUE)					\
+  {									\
+    long t[2];								\
+    REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);				\
+    fprintf (FILE, "\t%s\t0x%lx\n\t%s\t0x%lx\n",			\
+	     ASM_LONG, t[0], ASM_LONG, t[1]);				\
+  }
+
+/* This is how to output an assembler line defining a `float' constant.  */
+
+#define ASM_OUTPUT_FLOAT(FILE,VALUE)					\
+  {									\
+    long t;								\
+    REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);				\
+    fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t);			\
+  }									\
+
+/* This is how to output an assembler line defining a `long double'
+   constant.  */
+
+#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)				\
+  {									\
+    long t[4];								\
+    REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), t);			\
+    fprintf (FILE, "\t%s\t0x%lx\n\t%s\t0x%lx\n\t%s\t0x%lx\n\t%s\t0x%lx\n", \
+      ASM_LONG, t[0], ASM_LONG, t[1], ASM_LONG, t[2], ASM_LONG, t[3]);	\
+  }
+
+/* This is how to output an assembler line defining an `int' constant.  */
+
+#define ASM_OUTPUT_INT(FILE,VALUE)  \
+( fprintf (FILE, "\t%s\t", ASM_LONG),		\
+  output_addr_const (FILE, (VALUE)),		\
+  fprintf (FILE, "\n"))
+
+/* This is how to output an assembler line defining a DImode constant.  */
+#define ASM_OUTPUT_DOUBLE_INT(FILE,VALUE)  \
+  output_double_int (FILE, VALUE)
+
+/* Likewise for `char' and `short' constants.  */
+
+#define ASM_OUTPUT_SHORT(FILE,VALUE)  \
+( fprintf (FILE, "\t%s\t", ASM_SHORT),		\
+  output_addr_const (FILE, (VALUE)),		\
+  fprintf (FILE, "\n"))
+
+#define ASM_OUTPUT_CHAR(FILE,VALUE)  \
+( fprintf (FILE, "\t%s\t", ASM_BYTE_OP),	\
+  output_addr_const (FILE, (VALUE)),		\
+  fprintf (FILE, "\n"))
+
+/* This is how to output an assembler line for a numeric constant byte.  */
+
+#define ASM_OUTPUT_BYTE(FILE,VALUE)  \
+  fprintf (FILE, "\t%s\t0x%x\n", ASM_BYTE_OP, (VALUE))
+
+/* This is how to output an element of a case-vector that is absolute.  */
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
+do {									\
+  char label[30];							\
+  ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);			\
+  if (Pmode == SImode)							\
+    fprintf (FILE, "\t.word\t");					\
+  else if (TARGET_ENV32)						\
+    fprintf (FILE, "\t.word\t0\n\t.word\t");				\
+  else									\
+    fprintf (FILE, "\t.xword\t");					\
+  assemble_name (FILE, label);						\
+  fprintf (FILE, "\n");							\
+} while (0)
+
+/* This is how to output an element of a case-vector that is relative.
+   (SPARC uses such vectors only when generating PIC.)  */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)			\
+do {									\
+  char label[30];							\
+  ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);			\
+  if (Pmode == SImode)							\
+    fprintf (FILE, "\t.word\t");					\
+  else if (TARGET_ENV32)						\
+    fprintf (FILE, "\t.word\t0\n\t.word\t");				\
+  else									\
+    fprintf (FILE, "\t.xword\t");					\
+  assemble_name (FILE, label);						\
+  fprintf (FILE, "-1b\n");						\
+} while (0)
+
+/* This is how to output an assembler line
+   that says to advance the location counter
+   to a multiple of 2**LOG bytes.  */
+
+#define ASM_OUTPUT_ALIGN(FILE,LOG)	\
+  if ((LOG) != 0)			\
+    fprintf (FILE, "\t.align %d\n", (1<<(LOG)))
+
+#define ASM_OUTPUT_SKIP(FILE,SIZE)  \
+  fprintf (FILE, "\t.skip %u\n", (SIZE))
+
+/* This says how to output an assembler line
+   to define a global common symbol.  */
+
+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
+( fputs ("\t.common ", (FILE)),		\
+  assemble_name ((FILE), (NAME)),		\
+  fprintf ((FILE), ",%u,\"bss\"\n", (SIZE)))
+
+/* This says how to output an assembler line to define a local common
+   symbol.  */
+
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED)		\
+( fputs ("\t.reserve ", (FILE)),					\
+  assemble_name ((FILE), (NAME)),					\
+  fprintf ((FILE), ",%u,\"bss\",%u\n",					\
+	   (SIZE), ((ALIGNED) / BITS_PER_UNIT)))
+
+/* Store in OUTPUT a string (made with alloca) containing
+   an assembler-name for a local static variable named NAME.
+   LABELNO is an integer which is different for each call.  */
+
+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)	\
+( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),	\
+  sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+
+#define IDENT_ASM_OP ".ident"
+
+/* Output #ident as a .ident.  */
+
+#define ASM_OUTPUT_IDENT(FILE, NAME) \
+  fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME);
+
+/* Define the parentheses used to group arithmetic operations
+   in assembler code.  */
+
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* Define results of standard character escape sequences.  */
+#define TARGET_BELL 007
+#define TARGET_BS 010
+#define TARGET_TAB 011
+#define TARGET_NEWLINE 012
+#define TARGET_VT 013
+#define TARGET_FF 014
+#define TARGET_CR 015
+
+#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
+  ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(')
+
+/* Print operand X (an rtx) in assembler syntax to file FILE.
+   CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
+   For `%' followed by punctuation, CODE is the punctuation and X is null.  */
+
+#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
+
+/* Print a memory address as an operand to reference that memory location.  */
+
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
+{ register rtx base, index = 0;					\
+  int offset = 0;						\
+  register rtx addr = ADDR;					\
+  if (GET_CODE (addr) == REG)					\
+    fputs (reg_names[REGNO (addr)], FILE);			\
+  else if (GET_CODE (addr) == PLUS)				\
+    {								\
+      if (GET_CODE (XEXP (addr, 0)) == CONST_INT)		\
+	offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);\
+      else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)		\
+	offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\
+      else							\
+	base = XEXP (addr, 0), index = XEXP (addr, 1);		\
+      fputs (reg_names[REGNO (base)], FILE);			\
+      if (index == 0)						\
+	fprintf (FILE, "%+d", offset);				\
+      else if (GET_CODE (index) == REG)				\
+	fprintf (FILE, "+%s", reg_names[REGNO (index)]);	\
+      else if (GET_CODE (index) == SYMBOL_REF)			\
+	fputc ('+', FILE), output_addr_const (FILE, index);	\
+      else abort ();						\
+    }								\
+  else if (GET_CODE (addr) == MINUS				\
+	   && GET_CODE (XEXP (addr, 1)) == LABEL_REF)		\
+    {								\
+      output_addr_const (FILE, XEXP (addr, 0));			\
+      fputs ("-(", FILE);					\
+      output_addr_const (FILE, XEXP (addr, 1));			\
+      fputs ("-.)", FILE);					\
+    }								\
+  else if (GET_CODE (addr) == LO_SUM)				\
+    {								\
+      output_operand (XEXP (addr, 0), 0);			\
+      fputs ("+%lo(", FILE);					\
+      output_address (XEXP (addr, 1));				\
+      fputc (')', FILE);					\
+    }								\
+  else if (flag_pic && GET_CODE (addr) == CONST			\
+	   && GET_CODE (XEXP (addr, 0)) == MINUS		\
+	   && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST	\
+	   && GET_CODE (XEXP (XEXP (XEXP (addr, 0), 1), 0)) == MINUS	\
+	   && XEXP (XEXP (XEXP (XEXP (addr, 0), 1), 0), 1) == pc_rtx)	\
+    {								\
+      addr = XEXP (addr, 0);					\
+      output_addr_const (FILE, XEXP (addr, 0));			\
+      /* Group the args of the second CONST in parenthesis.  */	\
+      fputs ("-(", FILE);					\
+      /* Skip past the second CONST--it does nothing for us.  */\
+      output_addr_const (FILE, XEXP (XEXP (addr, 1), 0));	\
+      /* Close the parenthesis.  */				\
+      fputc (')', FILE);					\
+    }								\
+  else								\
+    {								\
+      output_addr_const (FILE, addr);				\
+    }								\
+}
+
+/* Declare functions defined in sparc.c and used in templates.  */
+
+extern char *singlemove_string ();
+extern char *output_move_double ();
+extern char *output_move_quad ();
+extern char *output_fp_move_double ();
+extern char *output_fp_move_quad ();
+extern char *output_block_move ();
+extern char *output_scc_insn ();
+extern char *output_cbranch ();
+extern char *output_v9branch ();
+extern char *output_return ();
+
+/* Defined in flags.h, but insn-emit.c does not include flags.h.  */
+
+extern int flag_pic;
--- libc-sparc-5.3.12.orig/libc/elf/crt/Makefile
+++ libc-sparc-5.3.12/libc/elf/crt/Makefile
@@ -35,13 +35,13 @@
 
 $(ELF_SHARED_DIR)/crtbeginS.o: crtstuff.c
 	$(CC) -DIN_GCC -DPOSIX  -O2 -fomit-frame-pointer -I. \
-		-fpic $(CRT_CFLAGS) \
+		-fPIC $(CRT_CFLAGS) \
 		-Iconfig -DCRT_BEGIN -finhibit-size-directive \
 		-fno-inline-functions -g0 -c $< -o $@
 
 $(ELF_SHARED_DIR)/crtendS.o: crtstuff.c
 	$(CC) -DIN_GCC -DPOSIX  -O2 -fomit-frame-pointer -I. \
-		-fpic $(CRT_CFLAGS) \
+		-fPIC $(CRT_CFLAGS) \
 		-Iconfig -DCRT_END -finhibit-size-directive \
 		-fno-inline-functions -g0 -c $< -o $@
 
@@ -59,13 +59,13 @@
 
 crtbeginS.s: crtstuff.c
 	$(CC) -DIN_GCC -DPOSIX  -O2 -fomit-frame-pointer -I. \
-		-fpic $(CRT_CFLAGS) \
+		-fPIC $(CRT_CFLAGS) \
 		-Iconfig -DCRT_BEGIN -finhibit-size-directive \
 		-fno-inline-functions -g0 -S $< -o $@
 
 crtendS.s: crtstuff.c
 	$(CC) -DIN_GCC -DPOSIX  -O2 -fomit-frame-pointer -I. \
-		-fpic $(CRT_CFLAGS) \
+		-fPIC $(CRT_CFLAGS) \
 		-Iconfig -DCRT_END -finhibit-size-directive \
 		-fno-inline-functions -g0 -S $< -o $@
 
@@ -108,6 +108,9 @@
 tm.h: config/m68k/linux.h
 	ln -s $? $@
 endif
+
+tm.h: config/sparc/linuxelf.h
+	ln -s $? $@
 
 depend:
 	@echo No dependency in `pwd`.
--- libc-sparc-5.3.12.orig/libc/elf/crt/crtstuff.c
+++ libc-sparc-5.3.12/libc/elf/crt/crtstuff.c
@@ -220,6 +220,8 @@
 static void
 __do_global_ctors_aux ()
 {
+    extern func_ptr __CTOR_END__[];
+    
   func_ptr *p;
   for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
     (*p) ();
--- libc-sparc-5.3.12.orig/libc/elf/crt/gbl-ctors.h
+++ libc-sparc-5.3.12/libc/elf/crt/gbl-ctors.h
@@ -41,6 +41,9 @@
 #endif
 #endif
 
+#if defined(__linux__) && defined(__sparc__)
+#undef ON_EXIT
+#endif
 /*  Declare a pointer to void function type.  */
 
 typedef void (*func_ptr) (void);
--- libc-sparc-5.3.12.orig/libc/elf/crt/pc.h
+++ libc-sparc-5.3.12/libc/elf/crt/pc.h
@@ -0,0 +1,238 @@
+/* Definitions for Intel 386 running Linux with ELF format
+   Written by Eric Youngdale.
+   Modified for stabs-in-ELF by H.J. Lu. */
+
+/* Use stabs instead of DWARF debug format.  */
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+/* A lie, I guess, but the general idea behind linux/ELF is that we are
+   supposed to be outputting something that will assemble under SVr4.
+   This gets us pretty close.  */
+#include "i386/i386.h"	/* Base i386 target machine definitions */
+#include "i386/att.h"	/* Use the i386 AT&T assembler syntax */
+#include "svr4.h"
+#undef MD_EXEC_PREFIX
+#undef MD_STARTFILE_PREFIX
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (i386 Linux/ELF)");
+/* Output at beginning of assembler file.  */
+/* The .file command should always begin the output.  */
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE)						\
+  do {									\
+	output_file_directive (FILE, main_input_filename);		\
+	fprintf (FILE, "\t.version\t\"01.01\"\n");			\
+  } while (0)
+/* The svr4 ABI for the i386 says that records and unions are returned
+   in memory.  */
+#undef DEFAULT_PCC_STRUCT_RETURN
+#define DEFAULT_PCC_STRUCT_RETURN 1
+/* This is how to output an element of a case-vector that is relative.
+   This is only used for PIC code.  See comments by the `casesi' insn in
+   i386.md for an explanation of the expression this outputs. */
+#undef ASM_OUTPUT_ADDR_DIFF_ELT
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
+  fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
+/* Indicate that jump tables go in the text section.  This is
+   necessary when compiling PIC code.  */
+#define JUMP_TABLES_IN_TEXT_SECTION
+/* Copy this from the svr4 specifications... */
+/* Define the register numbers to be used in Dwarf debugging information.
+   The SVR4 reference port C compiler uses the following register numbers
+   in its Dwarf output code:
+	0 for %eax (gnu regno = 0)
+	1 for %ecx (gnu regno = 2)
+	2 for %edx (gnu regno = 1)
+	3 for %ebx (gnu regno = 3)
+	4 for %esp (gnu regno = 7)
+	5 for %ebp (gnu regno = 6)
+	6 for %esi (gnu regno = 4)
+	7 for %edi (gnu regno = 5)
+   The following three DWARF register numbers are never generated by
+   the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
+   believes these numbers have these meanings.
+	8  for %eip    (no gnu equivalent)
+	9  for %eflags (no gnu equivalent)
+	10 for %trapno (no gnu equivalent)
+   It is not at all clear how we should number the FP stack registers
+   for the x86 architecture.  If the version of SDB on x86/svr4 were
+   a bit less brain dead with respect to floating-point then we would
+   have a precedent to follow with respect to DWARF register numbers
+   for x86 FP registers, but the SDB on x86/svr4 is so completely
+   broken with respect to FP registers that it is hardly worth thinking
+   of it as something to strive for compatibility with.
+   The verison of x86/svr4 SDB I have at the moment does (partially)
+   seem to believe that DWARF register number 11 is associated with
+   the x86 register %st(0), but that's about all.  Higher DWARF
+   register numbers don't seem to be associated with anything in
+   particular, and even for DWARF regno 11, SDB only seems to under-
+   stand that it should say that a variable lives in %st(0) (when
+   asked via an `=' command) if we said it was in DWARF regno 11,
+   but SDB still prints garbage when asked for the value of the
+   variable in question (via a `/' command).
+   (Also note that the labels SDB prints for various FP stack regs
+   when doing an `x' command are all wrong.)
+   Note that these problems generally don't affect the native SVR4
+   C compiler because it doesn't allow the use of -O with -g and
+   because when it is *not* optimizing, it allocates a memory
+   location for each floating-point variable, and the memory
+   location is what gets described in the DWARF AT_location
+   attribute for the variable in question.
+   Regardless of the severe mental illness of the x86/svr4 SDB, we
+   do something sensible here and we use the following DWARF
+   register numbers.  Note that these are all stack-top-relative
+   numbers.
+	11 for %st(0) (gnu regno = 8)
+	12 for %st(1) (gnu regno = 9)
+	13 for %st(2) (gnu regno = 10)
+	14 for %st(3) (gnu regno = 11)
+	15 for %st(4) (gnu regno = 12)
+	16 for %st(5) (gnu regno = 13)
+	17 for %st(6) (gnu regno = 14)
+	18 for %st(7) (gnu regno = 15)
+*/
+#undef DBX_REGISTER_NUMBER
+#define DBX_REGISTER_NUMBER(n) \
+((n) == 0 ? 0 \
+ : (n) == 1 ? 2 \
+ : (n) == 2 ? 1 \
+ : (n) == 3 ? 3 \
+ : (n) == 4 ? 6 \
+ : (n) == 5 ? 7 \
+ : (n) == 6 ? 5 \
+ : (n) == 7 ? 4 \
+ : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
+ : (-1))
+#define LINUX_ELF
+#include "i386/linux.h"
+
+#undef YES_UNDERSCORES
+#define NO_UNDERSCORES
+
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+   for profiling a function entry.  */
+
+#undef FUNCTION_PROFILER
+#define FUNCTION_PROFILER(FILE, LABELNO)  \
+{									\
+  if (flag_pic)								\
+    {									\
+      fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n",		\
+	       LPREFIX, (LABELNO));					\
+      fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n");			\
+    }									\
+  else									\
+    {									\
+      fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO));	\
+      fprintf (FILE, "\tcall mcount\n");				\
+    }									\
+}
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-D__ELF__ -Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)"
+
+#undef CPP_SPEC
+#if TARGET_CPU_DEFAULT == 2
+#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}"
+#else
+#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}"
+#endif
+
+#if 0
+
+#undef LINK_SPEC
+#define LINK_SPEC	"-m elf_i386 %{!ibcs:%{!static:%{!dynamic-linker:--dynamic-linker /lib/elf/ld-linux.so.1} %{!rpath:-rpath /lib/elf/}}}"
+
+#else
+
+#undef	LIB_SPEC
+#define LIB_SPEC \
+  "%{!shared: \
+     %{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \
+       %{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}"
+
+#undef	LIB_SPEC_2
+#define	LIB_SPEC_2 \
+  "%{!shared:-lgcc %L -lgcc}"
+
+#undef	LIBGCC_SPEC
+#define LIBGCC_SPEC \
+  "%{!shared:-lgcc}"
+
+
+/* Provide a LINK_SPEC appropriate for Linux.  Here we provide support
+   for the special GCC options -static and -shared, which allow us to
+   link things in one of these three modes by applying the appropriate
+   combinations of options at link-time. We like to support here for
+   as many of the other GNU linker options as possible. But I don't
+   have the time to search for those flags. I am sure how to add
+   support for -soname shared_object_name. H.J.
+
+   I took out %{v:%{!V:-V}}. It is too much :-(. They can use
+   -Wl,-V.
+
+   When the -shared link option is used a final link is not being
+   done.  */
+
+/* If ELF is the default format, we should not use /lib/elf. */
+
+#undef	LINK_SPEC
+#ifndef LINUX_DEFAULT_ELF
+#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
+  %{!shared: \
+    %{!ibcs: \
+      %{!static: \
+	%{rdynamic:-export-dynamic} \
+	%{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \
+	%{!rpath:-rpath /lib/elf/}} %{static:-static}}}"
+#else
+#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
+  %{!shared: \
+    %{!ibcs: \
+      %{!static: \
+	%{rdynamic:-export-dynamic} \
+	%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1} \
+	%{!rpath:-rpath /lib/}} %{static:-static}}}"
+#endif
+
+/* Provide a STARTFILE_SPEC appropriate for Linux.  Here we add
+   the Linux magical crtbegin.o file (see crtstuff.c) which
+   provides part of the support for getting C++ file-scope static
+   object constructed before entering `main'. */
+   
+#undef	STARTFILE_SPEC
+#if 0
+#define STARTFILE_SPEC \
+  "%{!shared: \
+     %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}} crti.o%s} \
+   %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+#else
+/* We use crtstuff.c from Jason. It needs crti.o for building the
+ * shared library.
+ */
+#define STARTFILE_SPEC \
+  "%{!shared: \
+     %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
+   crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+#endif
+
+/* Provide a ENDFILE_SPEC appropriate for Linux.  Here we tack on
+   the Linux magical crtend.o file (see crtstuff.c) which
+   provides part of the support for getting C++ file-scope static
+   object constructed before entering `main', followed by a normal
+   Linux "finalizer" file, which is either `gcrtn.o' or `crtn.o'.  */
+
+#undef	ENDFILE_SPEC
+#if 0
+#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} \
+   %{!shared:crtn.o%s}"
+#else
+/* We use crtstuff.c from Jason. It needs crtn.o for building the
+ * shared library.
+ */
+#define ENDFILE_SPEC \
+  "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+#endif
+
+#endif
--- libc-sparc-5.3.12.orig/libc/elf/crt/tm.h
+++ libc-sparc-5.3.12/libc/elf/crt/tm.h
@@ -0,0 +1,127 @@
+/* Definitions for Intel 386 running Linux
+   Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+   Contributed by H.J. Lu (hjl@nynexst.com)
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if 0	/* The FSF has fixed the known bugs. But ....... */
+
+/* Linux has a hacked gas 1.38.1, which can handle repz, repnz
+ and fildll.  */
+
+#define GOOD_GAS
+#endif
+
+#define LINUX_ELF
+#define OBJECT_FORMAT_ELF
+#define INIT_SECTION_ASM_OP ".section \".init\""
+#define LINUX_DEFAULT_ELF
+#include "sparc/sparc.h"
+
+#define FINI_SECTION_ASM_OP ".section \".fini\""
+/* Don't assume anything about the header files. */
+#define NO_IMPLICIT_EXTERN_C
+
+/* This is tested by i386/gas.h.  */
+#define YES_UNDERSCORES
+
+#ifndef LINUX_ELF
+#if 0
+#include "sparc/gstabs.h"
+#endif
+#endif
+
+/* Specify predefined symbols in preprocessor.  */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dunix -Dsparc -D__sparc__ -D__ELF__ -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)"
+
+#undef CPP_SPEC
+#if TARGET_CPU_DEFAULT == 2
+#define CPP_SPEC "%{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}"
+#else
+#define CPP_SPEC "%{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}"
+#endif
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+#undef HAVE_ATEXIT
+#define HAVE_ATEXIT
+
+/* Linux uses ctype from glibc.a. I am not sure how complete it is.
+   For now, we play safe. It may change later. */
+
+#if 0
+#undef MULTIBYTE_CHARS
+#define MULTIBYTE_CHARS	1
+#endif
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} %{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}"
+
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC  \
+  "%{pg:gcrt0.o%s -static} %{!pg:%{p:gcrt0.o%s -static} %{!p:crt0.o%s %{g*:-static} %{static:-static}}}"
+
+
+/* There are conflicting reports about whether this system uses
+   a different assembler syntax.  wilson@cygnus.com says # is right.  */
+#undef COMMENT_BEGIN
+#define COMMENT_BEGIN "#"
+
+#undef ASM_APP_ON
+#define ASM_APP_ON "#APP\n"
+
+#undef ASM_APP_OFF
+#define ASM_APP_OFF "#NO_APP\n"
+
+/* Don't default to pcc-struct-return, because gcc is the only compiler, and
+   we want to retain compatibility with older gcc versions.  */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* We need that too. */
+#define HANDLE_SYSV_PRAGMA
+
+#undef LINK_SPEC
+
+/* We want to pass -v to linker */
+#if TARGET_CPU_DEFAULT == 2
+#define LINK_SPEC	"%{v:-dll-verbose} %{!m386:-m486}"
+#else
+#define LINK_SPEC	"%{v:-dll-verbose} %{m486:-m486}"
+#endif
+#undef LINK_SPEC
+#define LINK_SPEC  "%{h*} %{V} %{v:%{!V:-V}} \
+   %{b} %{Wl,*:%*} \
+   %{static:-dn -Bstatic} \
+   %{shared:-G -dy -z text %{!h*:%{o*:-h %*}}} \
+   %{symbolic:-Bsymbolic -G -dy -z text %{!h*:%{o*:-h %*}}} \
+   %{G:-G} \
+   %{YP,*} \
+   %{R*} \
+   %{Qy:} %{!Qn:-Qy}"
--- libc-sparc-5.3.12.orig/libc/elf/Makefile
+++ libc-sparc-5.3.12/libc/elf/Makefile
@@ -13,7 +13,8 @@
 endif
 
 # Use the same version numbering as the jumptable a.out libraries.
-BUILD_ELFLIBS=libc libm libpthreads
+BUILD_ELFLIBS=libc libm 
+# libpthreads
 ELFLIBS=libc libm 
 
 CRTBEGIN=$(ELF_SHARED_DIR)/crtbeginS.o
@@ -35,7 +36,7 @@
 	  SHLIB_VERSION=`awk -F= ' { if ($$1 == "Version")  print $$2 }' $$JUMP_PARAMS`; \
 	  MAJOR_VERSION=`echo $$SHLIB_VERSION | sed 's/\..*//'`; \
 	  if [ "1" = "1" ]; then \
-	    $(CC) $(ELF_LDFLAGS) -B$(ELF_SHARED_DIR)/ \
+	    $(CC) $(ELF_LDFLAGS) -B/xx/$(ELF_SHARED_DIR)/ \
 		-o $(ELF_SHARED_DIR)/$$l.so.$$SHLIB_VERSION \
 		-Wl,-soname,$$l.so.$$MAJOR_VERSION \
 		`case $$l in \
--- libc-sparc-5.3.12.orig/libc/gcc/config/sparc/linux.h
+++ libc-sparc-5.3.12/libc/gcc/config/sparc/linux.h
@@ -0,0 +1,123 @@
+/* Definitions for Intel 386 running Linux
+   Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+   Contributed by H.J. Lu (hjl@nynexst.com)
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if 0	/* The FSF has fixed the known bugs. But ....... */
+
+/* Linux has a hacked gas 1.38.1, which can handle repz, repnz
+ and fildll.  */
+
+#define GOOD_GAS
+#endif
+
+#define LINUX_DEFAULT_ELF
+#include "sparc/sparc.h"
+
+/* Don't assume anything about the header files. */
+#define NO_IMPLICIT_EXTERN_C
+
+/* This is tested by i386/gas.h.  */
+#define YES_UNDERSCORES
+
+#ifndef LINUX_ELF
+#if 0
+#include "sparc/gstabs.h"
+#endif
+#endif
+
+/* Specify predefined symbols in preprocessor.  */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-Dunix -Dsparc -D__sparc__ -D__ELF__ -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)"
+
+#undef CPP_SPEC
+#if TARGET_CPU_DEFAULT == 2
+#define CPP_SPEC "%{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}"
+#else
+#define CPP_SPEC "%{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}"
+#endif
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+#undef HAVE_ATEXIT
+#define HAVE_ATEXIT
+
+/* Linux uses ctype from glibc.a. I am not sure how complete it is.
+   For now, we play safe. It may change later. */
+
+#if 0
+#undef MULTIBYTE_CHARS
+#define MULTIBYTE_CHARS	1
+#endif
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} %{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}"
+
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC  \
+  "%{pg:gcrt0.o%s -static} %{!pg:%{p:gcrt0.o%s -static} %{!p:crt0.o%s %{g*:-static} %{static:-static}}}"
+
+
+/* There are conflicting reports about whether this system uses
+   a different assembler syntax.  wilson@cygnus.com says # is right.  */
+#undef COMMENT_BEGIN
+#define COMMENT_BEGIN "#"
+
+#undef ASM_APP_ON
+#define ASM_APP_ON "#APP\n"
+
+#undef ASM_APP_OFF
+#define ASM_APP_OFF "#NO_APP\n"
+
+/* Don't default to pcc-struct-return, because gcc is the only compiler, and
+   we want to retain compatibility with older gcc versions.  */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* We need that too. */
+#define HANDLE_SYSV_PRAGMA
+
+#undef LINK_SPEC
+
+/* We want to pass -v to linker */
+#if TARGET_CPU_DEFAULT == 2
+#define LINK_SPEC	"%{v:-dll-verbose} %{!m386:-m486}"
+#else
+#define LINK_SPEC	"%{v:-dll-verbose} %{m486:-m486}"
+#endif
+#undef LINK_SPEC
+#define LINK_SPEC  "%{h*} %{V} %{v:%{!V:-V}} \
+   %{b} %{Wl,*:%*} \
+   %{static:-dn -Bstatic} \
+   %{shared:-G -dy -z text %{!h*:%{o*:-h %*}}} \
+   %{symbolic:-Bsymbolic -G -dy -z text %{!h*:%{o*:-h %*}}} \
+   %{G:-G} \
+   %{YP,*} \
+   %{R*} \
+   %{Qy:} %{!Qn:-Qy}"
--- libc-sparc-5.3.12.orig/libc/gcc/config/sparc/sparc.h
+++ libc-sparc-5.3.12/libc/gcc/config/sparc/sparc.h
@@ -0,0 +1,2586 @@
+/* Definitions of target machine for GNU compiler, for Sun SPARC.
+   Copyright (C) 1987, 88, 89, 92, 94, 1995 Free Software Foundation, Inc.
+   Contributed by Michael Tiemann (tiemann@cygnus.com).
+   64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+   at Cygnus Support.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Note that some other tm.h files include this one and then override
+   many of the definitions that relate to assembler syntax.  */
+
+/* Sparc64 support has been added by trying to allow for a day when one
+   compiler can handle both v8 and v9.  There are a few cases where this
+   isn't doable, but keep them to a minimum!  Two macros are used to help out:
+   TARGET_V9 is used to select (at runtime) !v9-ness or v9-ness.
+   SPARCV9 is defined when compiling for sparc64 only.
+   In places where it is possible to choose between the two at runtime, use
+   TARGET_V9.  In places where it is currently not possible to select
+   between the two at runtime use SPARCV9.  Again, keep uses of SPARCV9 to a
+   minimum.  No attempt is made to support both v8 and v9 in the v9 compiler.
+
+   If a combination v8/v9 compiler is too slow, it should always be possible
+   to #define TARGET_V9 as 0 (and potentially other v9-only options), and
+   #undef SPARCV9.  */
+
+/* What architecture we're compiling for.  This must coincide with the
+   `arch_type' attribute in the .md file.  The names were chosen to avoid
+   potential misunderstandings with the various 32 bit flavors (v7, v8, etc.):
+   if we used ARCH_V9 then we'd want to use something like ARCH_V8 but that
+   could be misleading and ARCH_NOTV9 sounds klunky.  */
+enum arch_type { ARCH_32BIT, ARCH_64BIT };
+extern enum arch_type sparc_arch_type;
+
+/* Names to predefine in the preprocessor for this target machine.  */
+
+/* ??? The GCC_NEW_VARARGS macro is now obsolete, because gcc always uses
+   the right varags.h file when bootstrapping.  */
+
+#ifdef SPARCV9
+#define CPP_PREDEFINES \
+  "-Dsparc -Dsun -Dunix -D__sparc_v9__ \
+   -Asystem(unix) -Asystem(bsd) -Acpu(sparc64) -Amachine(sparc64)"
+#else
+#define CPP_PREDEFINES \
+  "-Dsparc -Dsun -Dunix -D__GCC_NEW_VARARGS__ \
+   -Asystem(unix) -Asystem(bsd) -Acpu(sparc) -Amachine(sparc)"
+#endif
+
+#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} %{g:-lg}}"
+
+/* Provide required defaults for linker -e and -d switches.  */
+
+#define LINK_SPEC \
+ "%{!shared:%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp} %{static:-Bstatic} \
+  %{assert*} %{shared:-assert pure-text}"
+
+/* Special flags to the Sun-4 assembler when using pipe for input.  */
+
+#define ASM_SPEC \
+  " %| %{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-k}}} %{keep-local-as-symbols:-L}"
+
+/* Define macros to distinguish architectures.  */
+
+#ifdef SPARCV9
+#define CPP_SPEC "\
+%{mint64:-D__INT_MAX__=9223372036854775807LL -D__LONG_MAX__=9223372036854775807LL} \
+%{mlong64:-D__LONG_MAX__=9223372036854775807LL} \
+"
+#else
+#define CPP_SPEC "\
+%{msparclite:-D__sparclite__} \
+%{mf930:-D__sparclite__} %{mf934:-D__sparclite__} \
+%{mv8:-D__sparc_v8__} \
+%{msupersparc:-D__supersparc__ -D__sparc_v8__}	\
+"
+#endif
+
+/* Prevent error on `-sun4' and `-target sun4' options.  */
+/* This used to translate -dalign to -malign, but that is no good
+   because it can't turn off the usual meaning of making debugging dumps.  */
+
+#define CC1_SPEC "%{sun4:} %{target:}"
+
+#ifdef SPARCV9
+#define PTRDIFF_TYPE "long long int"
+#define SIZE_TYPE "long long unsigned int"
+#else
+#define PTRDIFF_TYPE "int"
+/* In 2.4 it should work to delete this.
+   #define SIZE_TYPE "int"  */
+#endif
+
+/* ??? This should be 32 bits for v9 but what can we do?  */
+#define WCHAR_TYPE "short unsigned int"
+#define WCHAR_TYPE_SIZE 16
+#define MAX_WCHAR_TYPE_SIZE 16
+
+/* Show we can debug even without a frame pointer.  */
+#define CAN_DEBUG_WITHOUT_FP
+
+/* To make profiling work with -f{pic,PIC}, we need to emit the profiling
+   code into the rtl.  Also, if we are profiling, we cannot eliminate
+   the frame pointer (because the return address will get smashed).  */
+
+void sparc_override_options ();
+
+#define OVERRIDE_OPTIONS \
+  do {									\
+    if (profile_flag || profile_block_flag)				\
+      {									\
+	if (flag_pic)							\
+	  {								\
+	    char *pic_string = (flag_pic == 1) ? "-fpic" : "-fPIC";	\
+	    warning ("%s and profiling conflict: disabling %s",		\
+		     pic_string, pic_string);				\
+	    flag_pic = 0;						\
+	  }								\
+	flag_omit_frame_pointer = 0;					\
+      }									\
+    SUBTARGET_OVERRIDE_OPTIONS;						\
+    sparc_override_options ();						\
+  } while (0)
+
+/* This is meant to be redefined in the host dependent files.  */
+#define SUBTARGET_OVERRIDE_OPTIONS
+
+/* These compiler options take an argument.  We ignore -target for now.  */
+
+#define WORD_SWITCH_TAKES_ARG(STR)				\
+ (DEFAULT_WORD_SWITCH_TAKES_ARG (STR)				\
+  || !strcmp (STR, "target") || !strcmp (STR, "assert"))
+
+/* Print subsidiary information on the compiler version in use.  */
+
+#define TARGET_VERSION fprintf (stderr, " (sparc)");
+
+/* Generate DBX debugging information.  */
+
+#define DBX_DEBUGGING_INFO
+
+/* Run-time compilation parameters selecting different hardware subsets.  */
+
+extern int target_flags;
+
+/* Nonzero if we should generate code to use the fpu.  */
+#define MASK_FPU 1
+#define TARGET_FPU (target_flags & MASK_FPU)
+
+/* Nonzero if we should use FUNCTION_EPILOGUE.  Otherwise, we
+   use fast return insns, but lose some generality.  */
+#define MASK_EPILOGUE 2
+#define TARGET_EPILOGUE (target_flags & MASK_EPILOGUE)
+
+/* Nonzero if we should assume that double pointers might be unaligned.
+   This can happen when linking gcc compiled code with other compilers,
+   because the ABI only guarantees 4 byte alignment.  */
+#define MASK_UNALIGNED_DOUBLES 4
+#define TARGET_UNALIGNED_DOUBLES (target_flags & MASK_UNALIGNED_DOUBLES)
+
+/* ??? Bits 0x18 are currently unused.  */
+
+/* Nonzero means we should schedule code for the TMS390Z55 SuperSparc chip.  */
+#define MASK_SUPERSPARC 0x20
+#define TARGET_SUPERSPARC (target_flags & MASK_SUPERSPARC)
+
+/* Nonzero means that we should generate code for a v8 sparc.  */
+#define MASK_V8 0x40
+#define TARGET_V8 (target_flags & MASK_V8)
+
+/* Nonzero means that we should generate code for a sparclite.
+   This enables the sparclite specific instructions, but does not affect
+   whether FPU instructions are emitted.  */
+#define MASK_SPARCLITE 0x80
+#define TARGET_SPARCLITE (target_flags & MASK_SPARCLITE)
+
+/* Nonzero means that we should generate code using a flat register window
+   model, i.e. no save/restore instructions are generated, in the most
+   efficient manner.  This code is not compatible with normal sparc code.  */
+/* This is not a user selectable option yet, because it requires changes
+   that are not yet switchable via command line arguments.  */
+/* ??? This flag is deprecated and may disappear at some point.  */
+#define MASK_FRW 0x100
+#define TARGET_FRW (target_flags & MASK_FRW)
+
+/* Nonzero means that we should generate code using a flat register window
+   model, i.e. no save/restore instructions are generated, but which is
+   compatible with normal sparc code.   This is the same as above, except
+   that the frame pointer is %i7 instead of %fp.  */
+/* ??? This use to be named TARGET_FRW_COMPAT.  At some point TARGET_FRW will
+   go away, but until that time only use this one when necessary.
+   -mflat sets both.  */
+#define MASK_FLAT 0x200
+#define TARGET_FLAT (target_flags & MASK_FLAT)
+
+/* Nonzero means use the registers that the Sparc ABI reserves for
+   application software.  This is the default for v8, but not v9.  */
+#define MASK_APP_REGS 0x400
+#define TARGET_APP_REGS (target_flags & MASK_APP_REGS)
+
+/*  Option to select how quad word floating point is implemented.
+    When TARGET_HARD_QUAD is true, we use the hardware quad instructions.
+    Otherwise, we use the SPARC ABI quad library functions.  */
+#define MASK_HARD_QUAD 0x800
+#define TARGET_HARD_QUAD (target_flags & MASK_HARD_QUAD)
+
+/* Nonzero if we're compiling for 64 bit sparc.  */
+#define MASK_V9 0x1000
+#define TARGET_V9 (target_flags & MASK_V9)
+
+/* Nonzero if ints are 64 bits.
+   This automatically implies longs are 64 bits too.
+   This option is for v9 only.  */
+#define MASK_INT64 0x2000
+#define TARGET_INT64 (target_flags & MASK_INT64)
+
+/* Nonzero if longs are 64 bits.
+   This option is for v9 only.  */
+#define MASK_LONG64 0x4000
+#define TARGET_LONG64 (target_flags & MASK_LONG64)
+
+/* Nonzero if pointers are 64 bits.
+   This is not a user selectable option, though it may be one day -
+   so it is used to determine pointer size instead of an architecture flag.  */
+#define MASK_PTR64 0x8000
+#define TARGET_PTR64 (target_flags & MASK_PTR64)
+
+/* Nonzero if we are generating code to be tested in a 32 bit environment.
+   Hence, we assume the upper 32 bits of symbolic addresses are zero, and
+   avoid generating %uhi and %ulo terms.
+   Pointers are still 64 bits though!  This option is for v9 only.  */
+/* ??? This option is deprecated.  Try to use -mmedlow.  */
+#define MASK_ENV32 0x10000
+#define TARGET_ENV32 (target_flags & MASK_ENV32)
+
+/* Memory models.
+   Two memory models are supported:
+   TARGET_MEDLOW: 32 bit address space, top 32 bits = 0
+                  (pointers still 64 bits)
+   TARGET_MEDANY: 32 bit address space, data segment loaded anywhere
+                  (use %g4 as offset).
+   TARGET_FULLANY: not supported yet.
+   These options are for v9 only.  All mask values are nonzero so the v8
+   compiler can assume this stuff won't interfere.  */
+#define MASK_MEDLOW 0x20000
+#define MASK_MEDANY 0x40000
+#define MASK_FULLANY 0x60000
+#define MASK_CODE_MODEL (MASK_MEDLOW + MASK_MEDANY)
+#define TARGET_MEDLOW ((target_flags & MASK_CODE_MODEL) == MASK_MEDLOW)
+#define TARGET_MEDANY ((target_flags & MASK_CODE_MODEL) == MASK_MEDANY)
+#define TARGET_FULLANY ((target_flags & MASK_CODE_MODEL) == MASK_FULLANY)
+
+/* ??? There are hardcoded references to this reg in the .md file.  */
+#define MEDANY_BASE_REG "%g4"
+
+/* Non-zero means use a stack bias of 2047.  Stack offsets are obtained by
+   adding 2047 to %sp.  This option is for v9 only and is the default.  */
+#define MASK_STACK_BIAS 0x80000
+#define TARGET_STACK_BIAS (target_flags & MASK_STACK_BIAS)
+
+/* Macro to define tables used to set the flags.
+   This is a list in braces of pairs in braces,
+   each pair being { "NAME", VALUE }
+   where VALUE is the bits to set or minus the bits to clear.
+   An empty string NAME is used to identify the default VALUE.  */
+
+/* The Fujitsu MB86930 is the original sparclite chip, with no fpu.
+   The Fujitsu MB86934 is the recent sparclite chip, with an fpu.
+   We use -mf930 and -mf934 options to choose which.
+   ??? These should perhaps be -mcpu= options.  */
+
+#define TARGET_SWITCHES  \
+  { {"fpu", MASK_FPU},			\
+    {"no-fpu", -MASK_FPU},		\
+    {"hard-float", MASK_FPU},		\
+    {"soft-float", -MASK_FPU},		\
+    {"epilogue", MASK_EPILOGUE},	\
+    {"no-epilogue", -MASK_EPILOGUE},	\
+    {"unaligned-doubles", MASK_UNALIGNED_DOUBLES}, \
+    {"no-unaligned-doubles", -MASK_UNALIGNED_DOUBLES}, \
+    {"supersparc", MASK_SUPERSPARC+MASK_V8},	\
+    {"cypress", -MASK_SUPERSPARC-MASK_V8},	\
+    {"v8", MASK_V8},			\
+    {"no-v8", -MASK_V8},		\
+    {"sparclite", MASK_SPARCLITE},	\
+    {"no-sparclite", -MASK_SPARCLITE},	\
+    {"f930", MASK_SPARCLITE},		\
+    {"f930", -MASK_FPU},		\
+    {"f934", MASK_SPARCLITE},		\
+    {"flat", MASK_FRW+MASK_FLAT},	\
+    {"no-flat", -(MASK_FRW+MASK_FLAT)},	\
+    {"app-regs", MASK_APP_REGS},	\
+    {"no-app-regs", -MASK_APP_REGS},	\
+    {"hard-quad-float", MASK_HARD_QUAD}, \
+    {"soft-quad-float", -MASK_HARD_QUAD}, \
+    SUBTARGET_SWITCHES			\
+    V9_SWITCHES				\
+    { "", TARGET_DEFAULT}}
+
+#define TARGET_DEFAULT (MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU)
+
+/* This is meant to be redefined in the host dependent files */
+#define SUBTARGET_SWITCHES
+
+/* ??? Until we support a combination v8/v9 compiler, the v9 specific options
+   are only defined for the v9 compiler.  */
+#ifdef SPARCV9
+#define V9_SWITCHES \
+/*  {"v9", MASK_V9}, */			\
+    {"int64", MASK_INT64+MASK_LONG64},	\
+    {"int32", -MASK_INT64},		\
+    {"int32", MASK_LONG64},		\
+    {"long64", -MASK_INT64},		\
+    {"long64", MASK_LONG64},		\
+    {"long32", -(MASK_INT64+MASK_LONG64)}, \
+/*  {"ptr64", MASK_PTR64}, */		\
+/*  {"ptr32", -MASK_PTR64}, */		\
+    {"stack-bias", MASK_STACK_BIAS},	\
+    {"no-stack-bias", -MASK_STACK_BIAS}, \
+    {"medlow", -MASK_CODE_MODEL},	\
+    {"medlow", MASK_MEDLOW},		\
+    {"medany", -MASK_CODE_MODEL},	\
+    {"medany", MASK_MEDANY},
+#else
+#define V9_SWITCHES
+#endif
+
+/* target machine storage layout */
+
+/* Define for cross-compilation to a sparc target with no TFmode from a host
+   with a different float format (e.g. VAX).  */
+#define REAL_ARITHMETIC
+
+/* Define this if most significant bit is lowest numbered
+   in instructions that operate on numbered bit-fields.  */
+#define BITS_BIG_ENDIAN 1
+
+/* Define this if most significant byte of a word is the lowest numbered.  */
+/* This is true on the SPARC.  */
+#define BYTES_BIG_ENDIAN 1
+
+/* Define this if most significant word of a multiword number is the lowest
+   numbered.  */
+/* Doubles are stored in memory with the high order word first.  This
+   matters when cross-compiling.  */
+#define WORDS_BIG_ENDIAN 1
+
+/* number of bits in an addressable storage unit */
+#define BITS_PER_UNIT 8
+
+/* Width in bits of a "word", which is the contents of a machine register.
+   Note that this is not necessarily the width of data type `int';
+   if using 16-bit ints on a 68000, this would still be 32.
+   But on a machine with 16-bit registers, this would be 16.  */
+#define BITS_PER_WORD		(TARGET_V9 ? 64 : 32)
+#define MAX_BITS_PER_WORD	64
+
+/* Width of a word, in units (bytes).  */
+#define UNITS_PER_WORD		(TARGET_V9 ? 8 : 4)
+#define MIN_UNITS_PER_WORD	4
+
+/* Now define the sizes of the C data types.  */
+
+#define SHORT_TYPE_SIZE		16
+#define INT_TYPE_SIZE		(TARGET_INT64 ? 64 : 32)
+#define LONG_TYPE_SIZE		(TARGET_LONG64 ? 64 : 32)
+#define LONG_LONG_TYPE_SIZE	64
+#define FLOAT_TYPE_SIZE		32
+#define DOUBLE_TYPE_SIZE	64
+
+#define MAX_INT_TYPE_SIZE	64
+#define MAX_LONG_TYPE_SIZE	64
+
+#ifdef SPARCV9
+/* ??? This does not work in SunOS 4.x, so it is not enabled here.
+   Instead, it is enabled in sol2.h, because it does work under Solaris.  */
+/* Define for support of TFmode long double and REAL_ARITHMETIC.
+   Sparc ABI says that long double is 4 words.  */
+#define LONG_DOUBLE_TYPE_SIZE 128
+#endif
+
+/* Width in bits of a pointer.
+   See also the macro `Pmode' defined below.  */
+#define POINTER_SIZE (TARGET_PTR64 ? 64 : 32)
+
+/* Allocation boundary (in *bits*) for storing arguments in argument list.  */
+#define PARM_BOUNDARY (TARGET_V9 ? 64 : 32)
+
+/* Boundary (in *bits*) on which stack pointer should be aligned.  */
+#define STACK_BOUNDARY (TARGET_V9 ? 128 : 64)
+
+/* ALIGN FRAMES on double word boundaries */
+
+#define SPARC_STACK_ALIGN(LOC) \
+  (TARGET_V9 ? (((LOC)+15) & ~15) : (((LOC)+7) & ~7))
+
+/* Allocation boundary (in *bits*) for the code of a function.  */
+#define FUNCTION_BOUNDARY 32
+
+/* Alignment of field after `int : 0' in a structure.  */
+/* ??? Should this be based on TARGET_INT64?  */
+#define EMPTY_FIELD_BOUNDARY (TARGET_V9 ? 64 : 32)
+
+/* Every structure's size must be a multiple of this.  */
+#define STRUCTURE_SIZE_BOUNDARY 8
+
+/* A bitfield declared as `int' forces `int' alignment for the struct.  */
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+/* No data type wants to be aligned rounder than this.  */
+#define BIGGEST_ALIGNMENT (TARGET_V9 ? 128 : 64)
+
+/* The best alignment to use in cases where we have a choice.  */
+#define FASTEST_ALIGNMENT 64
+
+/* Make strings word-aligned so strcpy from constants will be faster.  */
+#define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
+  ((TREE_CODE (EXP) == STRING_CST	\
+    && (ALIGN) < FASTEST_ALIGNMENT)	\
+   ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Make arrays of chars word-aligned for the same reasons.  */
+#define DATA_ALIGNMENT(TYPE, ALIGN)		\
+  (TREE_CODE (TYPE) == ARRAY_TYPE		\
+   && TYPE_MODE (TREE_TYPE (TYPE)) == QImode	\
+   && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Set this nonzero if move instructions will actually fail to work
+   when given unaligned data.  */
+#define STRICT_ALIGNMENT 1
+
+/* Things that must be doubleword aligned cannot go in the text section,
+   because the linker fails to align the text section enough!
+   Put them in the data section.  This macro is only used in this file.  */
+#define MAX_TEXT_ALIGN 32
+
+/* This forces all variables and constants to the data section when PIC.
+   This is because the SunOS 4 shared library scheme thinks everything in
+   text is a function, and patches the address to point to a loader stub.  */
+/* This is defined to zero for every system which doesn't use the a.out object
+   file format.  */
+#ifndef SUNOS4_SHARED_LIBRARIES
+#define SUNOS4_SHARED_LIBRARIES 0
+#endif
+
+/* This is defined differently for v9 in a cover file.  */
+#define SELECT_SECTION(T,RELOC)						\
+{									\
+  if (TREE_CODE (T) == VAR_DECL)					\
+    {									\
+      if (TREE_READONLY (T) && ! TREE_SIDE_EFFECTS (T)			\
+	  && DECL_INITIAL (T)						\
+	  && (DECL_INITIAL (T) == error_mark_node			\
+	      || TREE_CONSTANT (DECL_INITIAL (T)))			\
+	  && DECL_ALIGN (T) <= MAX_TEXT_ALIGN				\
+	  && ! (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES)))	\
+	text_section ();						\
+      else								\
+	data_section ();						\
+    }									\
+  else if (TREE_CODE (T) == CONSTRUCTOR)				\
+    {									\
+      if (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES))		\
+	data_section ();						\
+    }									\
+  else if (*tree_code_type[(int) TREE_CODE (T)] == 'c')			\
+    {									\
+      if ((TREE_CODE (T) == STRING_CST && flag_writable_strings)	\
+	  || TYPE_ALIGN (TREE_TYPE (T)) > MAX_TEXT_ALIGN		\
+	  || (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES)))	\
+	data_section ();						\
+      else								\
+	text_section ();						\
+    }									\
+}
+
+/* Use text section for a constant
+   unless we need more alignment than that offers.  */
+/* This is defined differently for v9 in a cover file.  */
+#define SELECT_RTX_SECTION(MODE, X)		\
+{						\
+  if (GET_MODE_BITSIZE (MODE) <= MAX_TEXT_ALIGN \
+      && ! (flag_pic && (symbolic_operand (X) || SUNOS4_SHARED_LIBRARIES)))  \
+    text_section ();				\
+  else						\
+    data_section ();				\
+}
+
+/* Standard register usage.  */
+
+/* Number of actual hardware registers.
+   The hardware registers are assigned numbers for the compiler
+   from 0 to just below FIRST_PSEUDO_REGISTER.
+   All registers that the compiler knows about must be given numbers,
+   even those that are not normally considered general registers.
+
+   SPARC has 32 integer registers and 32 floating point registers.
+   64 bit SPARC has 32 additional fp regs, but the odd numbered ones are not
+   accessible.  We still account for them to simplify register computations
+   (eg: in CLASS_MAX_NREGS).  There are also 4 fp condition code registers, so
+   32+32+32+4 == 100.
+   Register 0 is used as the integer condition code register.  */
+
+#ifdef SPARCV9
+#define FIRST_PSEUDO_REGISTER 100
+#else
+#define FIRST_PSEUDO_REGISTER 64
+#endif
+
+/* 1 for registers that have pervasive standard uses
+   and are not available for the register allocator.
+   g0 is used for the condition code and not to represent %g0, which is
+   hardwired to 0, so reg 0 is *not* fixed.
+   On non-v9 systems:
+   g1 is free to use as temporary.
+   g2-g4 are reserved for applications.  Gcc normally uses them as
+   temporaries, but this can be disabled via the -mno-app-regs option.
+   g5 through g7 are reserved for the operating system.
+   On v9 systems:
+   g1 and g5 are free to use as temporaries.
+   g2-g4 are reserved for applications (the compiler will not normally use
+   them, but they can be used as temporaries with -mapp-regs).
+   g6-g7 are reserved for the operating system.
+   ??? Register 1 is used as a temporary by the 64 bit sethi pattern, so must
+   currently be a fixed register until this pattern is rewritten.
+   Register 1 is also used when restoring call-preserved registers in large
+   stack frames.  */
+
+#ifdef SPARCV9
+#define FIXED_REGISTERS  \
+ {0, 1, 1, 1, 1, 0, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 1,	\
+				\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+				\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+				\
+  0, 0, 0, 0}
+#else
+#define FIXED_REGISTERS  \
+ {0, 0, 0, 0, 0, 1, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 1,	\
+				\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0}
+#endif
+
+/* 1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.  */
+
+#ifdef SPARCV9
+#define CALL_USED_REGISTERS  \
+ {1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 1,	\
+				\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+				\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+				\
+  1, 1, 1, 1}
+#else
+#define CALL_USED_REGISTERS  \
+ {1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 1,	\
+				\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1}
+#endif
+
+/* If !TARGET_FPU, then make the fp registers fixed so that they won't
+   be allocated.  On v9, also make the fp cc regs fixed.  */
+
+#define CONDITIONAL_REGISTER_USAGE				\
+do								\
+  {								\
+    if (! TARGET_FPU)						\
+      {								\
+	int regno;						\
+	for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno++) \
+	  fixed_regs[regno] = 1;				\
+      }								\
+    if (! TARGET_APP_REGS)					\
+      {								\
+	fixed_regs[2] = 1;					\
+	fixed_regs[3] = 1;					\
+	fixed_regs[4] = 1;					\
+      }								\
+    else							\
+      {								\
+	fixed_regs[2] = 0;					\
+	fixed_regs[3] = 0;					\
+	fixed_regs[4] = TARGET_MEDANY != 0;			\
+      }								\
+    if (TARGET_FLAT)						\
+      {								\
+	/* Let the compiler believe the frame pointer is still	\
+	   %fp, but output it as %i7.  */			\
+	fixed_regs[31] = 1;					\
+	reg_names[FRAME_POINTER_REGNUM] = "%i7";		\
+	/* ??? This is a hack to disable leaf functions.  */	\
+	global_regs[7] = 1;					\
+      }								\
+    if (profile_block_flag)					\
+      {								\
+	/* %g1 and %g2 must be fixed, because BLOCK_PROFILER	\
+	    uses them.  */					\
+	fixed_regs[1] = 1;					\
+	fixed_regs[2] = 1;					\
+      }								\
+  }								\
+while (0)
+
+/* Return number of consecutive hard regs needed starting at reg REGNO
+   to hold something of mode MODE.
+   This is ordinarily the length in words of a value of mode MODE
+   but can be less for certain modes in special long registers.
+
+   On SPARC, ordinary registers hold 32 bits worth;
+   this means both integer and floating point registers.
+   On v9, integer regs hold 64 bits worth; floating point regs hold
+   32 bits worth (this includes the new fp regs as even the odd ones are
+   included in the hard register count).  */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+  (TARGET_V9								\
+   ?  ((REGNO) < 32							\
+       ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD	\
+       : (GET_MODE_SIZE (MODE) + 3) / 4)				\
+   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+
+/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
+   See sparc.c for how we initialize this.  */
+extern int *hard_regno_mode_classes;
+extern int sparc_mode_class[];
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+  ((hard_regno_mode_classes[REGNO] & sparc_mode_class[MODE]) != 0)
+
+/* Value is 1 if it is a good idea to tie two pseudo registers
+   when one has mode MODE1 and one has mode MODE2.
+   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+   for any hard reg, then this must be 0 for correct output.
+
+   For V9: SFmode can't be combined with other float modes, because they can't
+   be allocated to the %d registers.  Also, DFmode won't fit in odd %f
+   registers, but SFmode will.  */
+#define MODES_TIEABLE_P(MODE1, MODE2) \
+  ((MODE1) == (MODE2)						\
+   || (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)		\
+       && (! TARGET_V9						\
+	   || (GET_MODE_CLASS (MODE1) != MODE_FLOAT		\
+	       || (MODE1 != SFmode && MODE2 != SFmode)))))
+
+/* Specify the registers used for certain standard purposes.
+   The values of these macros are register numbers.  */
+
+/* SPARC pc isn't overloaded on a register that the compiler knows about.  */
+/* #define PC_REGNUM  */
+
+/* Register to use for pushing function arguments.  */
+#define STACK_POINTER_REGNUM 14
+
+/* Actual top-of-stack address is 92/136 greater than the contents of the
+   stack pointer register for !v9/v9.  That is:
+   - !v9: 64 bytes for the in and local registers, 4 bytes for structure return
+     address, and 24 bytes for the 6 register parameters.
+   - v9: 128 bytes for the in and local registers + 8 bytes reserved.  */
+#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(0)
+
+/* The stack bias (amount by which the hardware register is offset by).  */
+#define SPARC_STACK_BIAS (TARGET_STACK_BIAS ? 2047 : 0)
+
+/* Base register for access to local variables of the function.  */
+#define FRAME_POINTER_REGNUM 30
+
+#if 0
+/* Register that is used for the return address.  */
+#define RETURN_ADDR_REGNUM 15
+#endif
+
+/* Value should be nonzero if functions must have frame pointers.
+   Zero means the frame pointer need not be set up (and parms
+   may be accessed via the stack pointer) in functions that seem suitable.
+   This is computed in `reload', in reload1.c.
+   Used in flow.c, global.c, and reload1.c.
+
+   Being a non-leaf function does not mean a frame pointer is needed in the
+   flat window model.  However, the debugger won't be able to backtrace through
+   us with out it.  */
+#define FRAME_POINTER_REQUIRED \
+  (TARGET_FRW ? (current_function_calls_alloca || current_function_varargs \
+		 || !leaf_function_p ()) \
+   : ! (leaf_function_p () && only_leaf_regs_used ()))
+
+/* C statement to store the difference between the frame pointer
+   and the stack pointer values immediately after the function prologue.
+
+   Note, we always pretend that this is a leaf function because if
+   it's not, there's no point in trying to eliminate the
+   frame pointer.  If it is a leaf function, we guessed right!  */
+#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
+  ((VAR) = (TARGET_FRW ? sparc_flat_compute_frame_size (get_frame_size ()) \
+	    : compute_frame_size (get_frame_size (), 1)))
+
+/* Base register for access to arguments of the function.  */
+#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
+
+/* Register in which static-chain is passed to a function.  This must
+   not be a register used by the prologue.
+   ??? v9: Since %g2 is reserved but %g5 is available, perhaps use %g5.  */
+#define STATIC_CHAIN_REGNUM 2
+
+/* Register which holds offset table for position-independent
+   data references.  */
+
+#define PIC_OFFSET_TABLE_REGNUM 23
+
+#define INITIALIZE_PIC initialize_pic ()
+#define FINALIZE_PIC finalize_pic ()
+
+/* Sparc ABI says that quad-precision floats and all structures are returned
+   in memory.
+   For v9, all aggregates are returned in memory.  */
+#define RETURN_IN_MEMORY(TYPE)				\
+  (TYPE_MODE (TYPE) == BLKmode				\
+   || (! TARGET_V9 && (TYPE_MODE (TYPE) == TFmode	\
+		       || TYPE_MODE (TYPE) == TCmode)))
+
+/* Functions which return large structures get the address
+   to place the wanted value at offset 64 from the frame.
+   Must reserve 64 bytes for the in and local registers.
+   v9: Functions which return large structures get the address to place the
+   wanted value from an invisible first argument.  */
+/* Used only in other #defines in this file.  */
+#define STRUCT_VALUE_OFFSET 64
+
+#define STRUCT_VALUE \
+  (TARGET_V9						\
+   ? 0							\
+   : gen_rtx (MEM, Pmode,				\
+	      gen_rtx (PLUS, Pmode, stack_pointer_rtx,	\
+		       gen_rtx (CONST_INT, VOIDmode, STRUCT_VALUE_OFFSET))))
+#define STRUCT_VALUE_INCOMING \
+  (TARGET_V9						\
+   ? 0							\
+   : gen_rtx (MEM, Pmode,				\
+	      gen_rtx (PLUS, Pmode, frame_pointer_rtx,	\
+		       gen_rtx (CONST_INT, VOIDmode, STRUCT_VALUE_OFFSET))))
+
+/* Define the classes of registers for register constraints in the
+   machine description.  Also define ranges of constants.
+
+   One of the classes must always be named ALL_REGS and include all hard regs.
+   If there is more than one class, another class must be named NO_REGS
+   and contain no registers.
+
+   The name GENERAL_REGS must be the name of a class (or an alias for
+   another name such as ALL_REGS).  This is the class of registers
+   that is allowed by "g" or "r" in a register constraint.
+   Also, registers outside this class are allocated only when
+   instructions express preferences for them.
+
+   The classes must be numbered in nondecreasing order; that is,
+   a larger-numbered class must never be contained completely
+   in a smaller-numbered class.
+
+   For any two classes, it is very desirable that there be another
+   class that represents their union.  */
+
+/* The SPARC has two kinds of registers, general and floating point.
+
+   For v9 we must distinguish between the upper and lower floating point
+   registers because the upper ones can't hold SFmode values.
+   HARD_REGNO_MODE_OK won't help here because reload assumes that register(s)
+   satisfying a group need for a class will also satisfy a single need for
+   that class.  EXTRA_FP_REGS is a bit of a misnomer as it covers all 64 fp
+   regs.
+
+   It is important that one class contains all the general and all the standard
+   fp regs.  Otherwise find_reg() won't properly allocate int regs for moves,
+   because reg_class_record() will bias the selection in favor of fp regs,
+   because reg_class_subunion[GENERAL_REGS][FP_REGS] will yield FP_REGS,
+   because FP_REGS > GENERAL_REGS.
+
+   It is also important that one class contain all the general and all the
+   fp regs.  Otherwise when spilling a DFmode reg, it may be from EXTRA_FP_REGS
+   but find_reloads() may use class GENERAL_OR_FP_REGS. This will cause
+   allocate_reload_reg() to bypass it causing an abort because the compiler
+   thinks it doesn't have a spill reg when in fact it does.
+
+   v9 also has 4 floating point condition code registers.  Since we don't
+   have a class that is the union of FPCC_REGS with either of the others,
+   it is important that it appear first.  Otherwise the compiler will die
+   trying to compile _fixunsdfsi because fix_truncdfsi2 won't match its
+   constraints.  */
+
+#ifdef SPARCV9
+enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS,
+		 GENERAL_OR_FP_REGS, GENERAL_OR_EXTRA_FP_REGS,
+		 ALL_REGS, LIM_REG_CLASSES };
+#else
+enum reg_class { NO_REGS, GENERAL_REGS, FP_REGS, ALL_REGS, LIM_REG_CLASSES };
+#endif
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file.   */
+
+#ifdef SPARCV9
+#define REG_CLASS_NAMES \
+  { "NO_REGS", "FPCC_REGS", "GENERAL_REGS", "FP_REGS", "EXTRA_FP_REGS", \
+    "GENERAL_OR_FP_REGS", "GENERAL_OR_EXTRA_FP_REGS", "ALL_REGS" }
+#else
+#define REG_CLASS_NAMES \
+  { "NO_REGS", "GENERAL_REGS", "FP_REGS", "ALL_REGS" }
+#endif
+
+/* Define which registers fit in which classes.
+   This is an initializer for a vector of HARD_REG_SET
+   of length N_REG_CLASSES.  */
+
+#ifdef SPARCV9
+#define REG_CLASS_CONTENTS \
+  {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {-2, 0, 0, 0}, \
+   {0, -1, 0, 0}, {0, -1, -1, 0}, {-2, -1, 0, 0}, {-2, -1, -1, 0}, \
+   {-2, -1, -1, 0xf}}
+#else
+#if 0 && defined (__GNUC__)
+#define REG_CLASS_CONTENTS {0LL, 0xfffffffeLL, 0xffffffff00000000LL, 0xfffffffffffffffeLL}
+#else
+#define REG_CLASS_CONTENTS {{0, 0}, {-2, 0}, {0, -1}, {-2, -1}}
+#endif
+#endif
+
+/* The same information, inverted:
+   Return the class number of the smallest class containing
+   reg number REGNO.  This could be a conditional expression
+   or could index an array.  */
+
+#ifdef SPARCV9
+#define REGNO_REG_CLASS(REGNO) \
+  ((REGNO) == 0 ? NO_REGS		\
+   : (REGNO) < 32 ? GENERAL_REGS	\
+   : (REGNO) < 64 ? FP_REGS		\
+   : (REGNO) < 96 ? EXTRA_FP_REGS	\
+   : FPCC_REGS)
+#else
+#define REGNO_REG_CLASS(REGNO) \
+  ((REGNO) >= 32 ? FP_REGS : (REGNO) == 0 ? NO_REGS : GENERAL_REGS)
+#endif
+
+/* This is the order in which to allocate registers normally.  
+   
+   We put %f0/%f1 last among the float registers, so as to make it more
+   likely that a pseudo-register which dies in the float return register
+   will get allocated to the float return register, thus saving a move
+   instruction at the end of the function.
+
+   On v9, the float registers are ordered a little "funny" because some
+   of them (%f16-%f47) are call-preserved.  */
+#ifdef SPARCV9
+#define REG_ALLOC_ORDER \
+{ 8, 9, 10, 11, 12, 13,			\
+  15, 16, 17, 18, 19, 20, 21, 22,	\
+  23, 24, 25, 26, 27, 28, 29, 31,	\
+  34, 35, 36, 37, 38, 39,		/* %f2-%f7 */   \
+  40, 41, 42, 43, 44, 45, 46, 47,	/* %f8-%f15 */  \
+  80, 81, 82, 83, 84, 85, 86, 87,	/* %f48-%f55 */ \
+  88, 89, 90, 91, 92, 93, 94, 95,	/* %f56-%f63 */ \
+  48, 49, 50, 51, 52, 53, 54, 55,	/* %f16-%f23 */ \
+  56, 57, 58, 59, 60, 61, 62, 63,	/* %f24-%f31 */ \
+  64, 65, 66, 67, 68, 69, 70, 71,	/* %f32-%f39 */ \
+  72, 73, 74, 75, 76, 77, 78, 79,	/* %f40-%f47 */ \
+  32, 33,				/* %f0,%f1 */   \
+  96, 97, 98, 99,			/* %fcc0-3 */   \
+  1, 5, 2, 3, 4, 6, 7, 0, 14, 30}
+#else
+#define REG_ALLOC_ORDER \
+{ 8, 9, 10, 11, 12, 13, 2, 3, 		\
+  15, 16, 17, 18, 19, 20, 21, 22, 	\
+  23, 24, 25, 26, 27, 28, 29, 31,	\
+  34, 35, 36, 37, 38, 39,		\
+  40, 41, 42, 43, 44, 45, 46, 47,	\
+  48, 49, 50, 51, 52, 53, 54, 55,	\
+  56, 57, 58, 59, 60, 61, 62, 63,	\
+  32, 33,				\
+  1, 4, 5, 6, 7, 0, 14, 30}
+#endif
+
+/* This is the order in which to allocate registers for
+   leaf functions.  If all registers can fit in the "i" registers,
+   then we have the possibility of having a leaf function.
+   v9: The floating point registers are ordered a little "funny" because some
+   of them (%f16-%f47) are call-preserved.   */
+#ifdef SPARCV9
+#define REG_LEAF_ALLOC_ORDER \
+{ 24, 25, 26, 27, 28, 29,		\
+  15, 8, 9, 10, 11, 12, 13,		\
+  16, 17, 18, 19, 20, 21, 22, 23,	\
+  34, 35, 36, 37, 38, 39,		\
+  40, 41, 42, 43, 44, 45, 46, 47,	\
+  80, 81, 82, 83, 84, 85, 86, 87,	\
+  88, 89, 90, 91, 92, 93, 94, 95,	\
+  48, 49, 50, 51, 52, 53, 54, 55,	\
+  56, 57, 58, 59, 60, 61, 62, 63,	\
+  64, 65, 66, 67, 68, 69, 70, 71,	\
+  72, 73, 74, 75, 76, 77, 78, 79,	\
+  32, 33,				\
+  96, 97, 98, 99,			\
+  1, 5, 2, 3, 4, 6, 7, 0, 14, 30, 31}
+#else
+#define REG_LEAF_ALLOC_ORDER \
+{ 2, 3, 24, 25, 26, 27, 28, 29,		\
+  15, 8, 9, 10, 11, 12, 13,		\
+  16, 17, 18, 19, 20, 21, 22, 23,	\
+  34, 35, 36, 37, 38, 39,		\
+  40, 41, 42, 43, 44, 45, 46, 47,	\
+  48, 49, 50, 51, 52, 53, 54, 55,	\
+  56, 57, 58, 59, 60, 61, 62, 63,	\
+  32, 33,				\
+  1, 4, 5, 6, 7, 0, 14, 30, 31}
+#endif
+
+#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
+
+/* ??? %g7 is not a leaf register to effectively #undef LEAF_REGISTERS when
+   -mflat is used.  Function only_leaf_regs_used will return 0 if a global
+   register is used and is not permitted in a leaf function.  We make %g7
+   a global reg if -mflat and voila.  Since %g7 is a system register and is
+   fixed it won't be used by gcc anyway.  */
+#ifdef SPARCV9
+#define LEAF_REGISTERS \
+{ 1, 1, 1, 1, 1, 1, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  1, 1, 1, 1, 1, 1, 0, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1}
+#else
+#define LEAF_REGISTERS \
+{ 1, 1, 1, 1, 1, 1, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 1, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  1, 1, 1, 1, 1, 1, 0, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1}
+#endif
+
+extern char leaf_reg_remap[];
+#define LEAF_REG_REMAP(REGNO) (leaf_reg_remap[REGNO])
+
+/* The class value for index registers, and the one for base regs.  */
+#define INDEX_REG_CLASS GENERAL_REGS
+#define BASE_REG_CLASS GENERAL_REGS
+
+/* Local macro to handle the two v9 classes of FP regs.  */
+#ifdef SPARCV9
+#define FP_REG_CLASS_P(CLASS) ((CLASS) == FP_REGS || (CLASS) == EXTRA_FP_REGS)
+#else
+#define FP_REG_CLASS_P(CLASS) ((CLASS) == FP_REGS)
+#endif
+
+/* Get reg_class from a letter such as appears in the machine description.  */
+
+#ifdef SPARCV9
+#define REG_CLASS_FROM_LETTER(C) \
+  ((C) == 'f' ? FP_REGS		\
+   : (C) == 'e' ? EXTRA_FP_REGS	\
+   : (C) == 'c' ? FPCC_REGS	\
+   : NO_REGS)
+#else
+/* Coerce v9's 'e' class to 'f', so we can use 'e' in the .md file for
+   v8 and v9.  */
+#define REG_CLASS_FROM_LETTER(C) \
+  ((C) == 'f' ? FP_REGS : (C) == 'e' ? FP_REGS : NO_REGS)
+#endif
+
+/* The letters I, J, K, L and M in a register constraint string
+   can be used to stand for particular ranges of immediate operands.
+   This macro defines what the ranges are.
+   C is the letter, and VALUE is a constant value.
+   Return 1 if VALUE is in the range specified by C.
+
+   For SPARC, `I' is used for the range of constants an insn
+   can actually contain.
+   `J' is used for the range which is just zero (since that is R0).
+   `K' is used for constants which can be loaded with a single sethi insn.  */
+
+#define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x1000) < 0x2000)
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C)  \
+  ((C) == 'I' ? (unsigned) ((VALUE) + 0x1000) < 0x2000	\
+   : (C) == 'J' ? (VALUE) == 0				\
+   : (C) == 'K' ? ((VALUE) & 0x3ff) == 0		\
+   : 0)
+
+/* Similar, but for floating constants, and defining letters G and H.
+   Here VALUE is the CONST_DOUBLE rtx itself.  */
+
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)	\
+  ((C) == 'G' ? fp_zero_operand (VALUE)			\
+   : (C) == 'H' ? arith_double_operand (VALUE, DImode)	\
+   : 0)
+
+/* Given an rtx X being reloaded into a reg required to be
+   in class CLASS, return the class of reg to actually use.
+   In general this is just CLASS; but on some machines
+   in some cases it is preferable to use a more restrictive class.  */
+/* We can't load constants into FP registers.  We can't load any FP constant
+   if an 'E' constraint fails to match it.  */
+#define PREFERRED_RELOAD_CLASS(X,CLASS)			\
+  (CONSTANT_P (X)					\
+   && (FP_REG_CLASS_P (CLASS)				\
+       || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT	\
+	   && (HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT	\
+	       || HOST_BITS_PER_INT != BITS_PER_WORD)))	\
+   ? NO_REGS : (CLASS))
+
+/* Return the register class of a scratch register needed to load IN into
+   a register of class CLASS in MODE.
+
+   On the SPARC, when PIC, we need a temporary when loading some addresses
+   into a register.
+
+   Also, we need a temporary when loading/storing a HImode/QImode value
+   between memory and the FPU registers.  This can happen when combine puts
+   a paradoxical subreg in a float/fix conversion insn.  */
+
+#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN)		\
+  ((FP_REG_CLASS_P (CLASS) && ((MODE) == HImode || (MODE) == QImode) \
+    && (GET_CODE (IN) == MEM					\
+	|| ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG)	\
+	    && true_regnum (IN) == -1))) ? GENERAL_REGS : NO_REGS)
+
+#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN)		\
+  ((FP_REG_CLASS_P (CLASS) && ((MODE) == HImode || (MODE) == QImode) \
+    && (GET_CODE (IN) == MEM					\
+	|| ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG)	\
+	    && true_regnum (IN) == -1))) ? GENERAL_REGS : NO_REGS)
+
+/* On SPARC it is not possible to directly move data between 
+   GENERAL_REGS and FP_REGS.  */
+#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
+  (FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2))
+
+/* Return the stack location to use for secondary memory needed reloads.
+   We want to use the reserved location just below the frame pointer.
+   However, we must ensure that there is a frame, so use assign_stack_local
+   if the frame size is zero.  */
+#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
+  (get_frame_size () == 0						\
+   ? assign_stack_local (MODE, GET_MODE_SIZE (MODE), 0)			\
+   : gen_rtx (MEM, MODE, gen_rtx (PLUS, Pmode, frame_pointer_rtx,	\
+				  GEN_INT (STARTING_FRAME_OFFSET))))
+
+/* Get_secondary_mem widens it's argument to BITS_PER_WORD which loses on v9
+   because the movsi and movsf patterns don't handle r/f moves.
+   For v8 we copy the default definition.  */
+#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \
+  (TARGET_V9							\
+   ? (GET_MODE_BITSIZE (MODE) < 32				\
+      ? mode_for_size (32, GET_MODE_CLASS (MODE), 0)		\
+      : MODE)							\
+   : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD			\
+      ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0)	\
+      : MODE))
+
+/* Return the maximum number of consecutive registers
+   needed to represent mode MODE in a register of class CLASS.  */
+/* On SPARC, this is the size of MODE in words.  */
+#define CLASS_MAX_NREGS(CLASS, MODE)	\
+  (FP_REG_CLASS_P (CLASS) ? (GET_MODE_SIZE (MODE) + 3) / 4 \
+   : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* Stack layout; function entry, exit and calling.  */
+
+/* Define the number of register that can hold parameters.
+   These two macros are used only in other macro definitions below.
+   MODE is the mode of the argument.
+   !v9: All args are passed in %o0-%o5.
+   v9: Non-float args are passed in %o0-5 and float args are passed in
+   %f0-%f15.  */
+#define NPARM_REGS(MODE) \
+  (TARGET_V9 ? (GET_MODE_CLASS (MODE) == MODE_FLOAT ? 16 : 6) : 6)
+
+/* Define this if pushing a word on the stack
+   makes the stack pointer a smaller address.  */
+#define STACK_GROWS_DOWNWARD
+
+/* Define this if the nominal address of the stack frame
+   is at the high-address end of the local variables;
+   that is, each additional local variable allocated
+   goes at a more negative offset in the frame.  */
+#define FRAME_GROWS_DOWNWARD
+
+/* Offset within stack frame to start allocating local variables at.
+   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
+   first local allocated.  Otherwise, it is the offset to the BEGINNING
+   of the first local allocated.  */
+/* This allows space for one TFmode floating point value.  */
+#define STARTING_FRAME_OFFSET \
+  (TARGET_V9 ? (SPARC_STACK_BIAS - 16) \
+   : (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)))
+
+/* If we generate an insn to push BYTES bytes,
+   this says how many the stack pointer really advances by.
+   On SPARC, don't define this because there are no push insns.  */
+/*  #define PUSH_ROUNDING(BYTES) */
+
+/* Offset of first parameter from the argument pointer register value.
+   !v9: This is 64 for the ins and locals, plus 4 for the struct-return reg
+   even if this function isn't going to use it.
+   v9: This is 128 for the ins and locals, plus a reserved space of 8.  */
+#define FIRST_PARM_OFFSET(FNDECL) \
+  (TARGET_V9 ? (SPARC_STACK_BIAS + 136) \
+   : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD))
+
+/* When a parameter is passed in a register, stack space is still
+   allocated for it.  */
+#ifndef SPARCV9
+#define REG_PARM_STACK_SPACE(DECL) (NPARM_REGS (SImode) * UNITS_PER_WORD)
+#endif
+
+/* Keep the stack pointer constant throughout the function.
+   This is both an optimization and a necessity: longjmp
+   doesn't behave itself when the stack pointer moves within
+   the function!  */
+#define ACCUMULATE_OUTGOING_ARGS
+
+/* Value is the number of bytes of arguments automatically
+   popped when returning from a subroutine call.
+   FUNDECL is the declaration node of the function (as a tree),
+   FUNTYPE is the data type of the function (as a tree),
+   or for a library call it is an identifier node for the subroutine name.
+   SIZE is the number of bytes of arguments passed on the stack.  */
+
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
+
+/* Some subroutine macros specific to this machine.
+   When !TARGET_FPU, put float return values in the general registers,
+   since we don't have any fp registers.  */
+#define BASE_RETURN_VALUE_REG(MODE) \
+  (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 8) \
+   : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 : 8))
+#define BASE_OUTGOING_VALUE_REG(MODE) \
+  (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 \
+		: TARGET_FRW ? 8 : 24) \
+   : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32	\
+      : (TARGET_FRW ? 8 : 24)))
+#define BASE_PASSING_ARG_REG(MODE) \
+  (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 8) \
+   : (8))
+#define BASE_INCOMING_ARG_REG(MODE) \
+  (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 \
+		: TARGET_FRW ? 8 : 24) \
+   : (TARGET_FRW ? 8 : 24))
+
+/* Define this macro if the target machine has "register windows".  This
+   C expression returns the register number as seen by the called function
+   corresponding to register number OUT as seen by the calling function.
+   Return OUT if register number OUT is not an outbound register.  */
+
+#define INCOMING_REGNO(OUT) \
+ ((TARGET_FRW || (OUT) < 8 || (OUT) > 15) ? (OUT) : (OUT) + 16)
+
+/* Define this macro if the target machine has "register windows".  This
+   C expression returns the register number as seen by the calling function
+   corresponding to register number IN as seen by the called function.
+   Return IN if register number IN is not an inbound register.  */
+
+#define OUTGOING_REGNO(IN) \
+ ((TARGET_FRW || (IN) < 24 || (IN) > 31) ? (IN) : (IN) - 16)
+
+/* Define how to find the value returned by a function.
+   VALTYPE is the data type of the value (as a tree).
+   If the precise function being called is known, FUNC is its FUNCTION_DECL;
+   otherwise, FUNC is 0.  */
+
+/* On SPARC the value is found in the first "output" register.  */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC)  \
+  gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE)))
+
+/* But the called function leaves it in the first "input" register.  */
+
+#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC)  \
+  gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_OUTGOING_VALUE_REG (TYPE_MODE (VALTYPE)))
+
+/* Define how to find the value returned by a library function
+   assuming the value has mode MODE.  */
+
+#define LIBCALL_VALUE(MODE)	\
+  gen_rtx (REG, MODE, BASE_RETURN_VALUE_REG (MODE))
+
+/* 1 if N is a possible register number for a function value
+   as seen by the caller.
+   On SPARC, the first "output" reg is used for integer values,
+   and the first floating point register is used for floating point values.  */
+
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 8 || (N) == 32)
+
+/* Define the size of space to allocate for the return value of an
+   untyped_call.  */
+
+#define APPLY_RESULT_SIZE 16
+
+/* 1 if N is a possible register number for function argument passing.
+   On SPARC, these are the "output" registers.  v9 also uses %f0-%f15.  */
+
+#define FUNCTION_ARG_REGNO_P(N) \
+  (TARGET_V9 ? (((N) < 14 && (N) > 7) || (N) > 31 && (N) < 48) \
+   : ((N) < 14 && (N) > 7))
+
+/* Define a data type for recording info about an argument list
+   during the scan of that argument list.  This data type should
+   hold all necessary information about the function itself
+   and about the args processed so far, enough to enable macros
+   such as FUNCTION_ARG to determine where the next arg should go.
+
+   On SPARC (!v9), this is a single integer, which is a number of words
+   of arguments scanned so far (including the invisible argument,
+   if any, which holds the structure-value-address).
+   Thus 7 or more means all following args should go on the stack.
+
+   For v9, we record how many of each type has been passed.  Different
+   types get passed differently.
+
+	- Float args are passed in %f0-15, after which they go to the stack
+	  where floats and doubles are passed 8 byte aligned and long doubles
+	  are passed 16 byte aligned.
+	- All aggregates are passed by reference.  The callee copies
+	  the structure if necessary, except if stdarg/varargs and the struct
+	  matches the ellipse in which case the caller makes a copy.
+	- Any non-float argument might be split between memory and reg %o5.
+	  ??? I don't think this can ever happen now that structs are no
+	  longer passed in regs.
+
+   For v9 return values:
+
+	- For all aggregates, the caller allocates space for the return value,
+          and passes the pointer as an implicit first argument, which is
+          allocated like all other arguments.
+	- The unimp instruction stuff for structure returns is gone.  */
+
+#ifdef SPARCV9
+enum sparc_arg_class { SPARC_ARG_INT = 0, SPARC_ARG_FLOAT = 1 };
+struct sparc_args {
+    int arg_count[2];	/* must be int! (for __builtin_args_info) */
+};
+#define CUMULATIVE_ARGS struct sparc_args
+
+/* Return index into CUMULATIVE_ARGS.  */
+
+#define GET_SPARC_ARG_CLASS(MODE) \
+  (GET_MODE_CLASS (MODE) == MODE_FLOAT ? SPARC_ARG_FLOAT : SPARC_ARG_INT)
+
+/* Round a register number up to a proper boundary for an arg of mode MODE.
+   This macro is only used in this file.
+
+   The "& (0x10000 - ...)" is used to round up to the next appropriate reg.  */
+
+#define ROUND_REG(CUM, MODE)				\
+  (GET_MODE_CLASS (MODE) != MODE_FLOAT			\
+   ? (CUM).arg_count[(int) GET_SPARC_ARG_CLASS (MODE)]	\
+   : ((CUM).arg_count[(int) GET_SPARC_ARG_CLASS (MODE)]	\
+      + GET_MODE_UNIT_SIZE (MODE) / 4 - 1)		\
+     & (0x10000 - GET_MODE_UNIT_SIZE (MODE) / 4))
+
+#define ROUND_ADVANCE(SIZE)	\
+  (((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+#else /* ! SPARCV9 */
+#define CUMULATIVE_ARGS int
+
+#define ROUND_REG(CUM, MODE) (CUM)
+
+#define ROUND_ADVANCE(SIZE)	\
+  ((SIZE + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+#endif /* ! SPARCV9 */
+
+/* Initialize a variable CUM of type CUMULATIVE_ARGS
+   for a call to a function whose data type is FNTYPE.
+   For a library call, FNTYPE is 0.
+
+   On SPARC, the offset always starts at 0: the first parm reg is always
+   the same reg.  */
+
+#ifdef SPARCV9
+extern int sparc_arg_count,sparc_n_named_args;
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME)		\
+  do {								\
+    (CUM).arg_count[(int) SPARC_ARG_INT] = 0;			\
+    (CUM).arg_count[(int) SPARC_ARG_FLOAT] = 0;			\
+    sparc_arg_count = 0;					\
+    sparc_n_named_args =					\
+      ((FNTYPE) && TYPE_ARG_TYPES (FNTYPE)			\
+       ? (list_length (TYPE_ARG_TYPES (FNTYPE))			\
+	  + (TREE_CODE (TREE_TYPE (FNTYPE)) == RECORD_TYPE	\
+	     || TREE_CODE (TREE_TYPE (FNTYPE)) == UNION_TYPE))	\
+       /* Can't tell, treat 'em all as named.  */		\
+       : 10000);						\
+  } while (0)
+#else
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) ((CUM) = 0)
+#endif
+
+/* Update the data in CUM to advance over an argument
+   of mode MODE and data type TYPE.
+   (TYPE is null for libcalls where that information may not be available.)  */
+
+#ifdef SPARCV9
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)		\
+  do {								\
+    (CUM).arg_count[(int) GET_SPARC_ARG_CLASS (MODE)] =		\
+      ROUND_REG ((CUM), (MODE))					\
+	+ (GET_MODE_CLASS (MODE) == MODE_FLOAT			\
+	   ? GET_MODE_SIZE (MODE) / 4				\
+	   : ROUND_ADVANCE ((MODE) == BLKmode			\
+			    ? GET_MODE_SIZE (Pmode)		\
+			    : GET_MODE_SIZE (MODE)));		\
+    sparc_arg_count++;						\
+  } while (0)
+#else
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)	\
+  ((CUM) += ((MODE) != BLKmode				\
+	     ? ROUND_ADVANCE (GET_MODE_SIZE (MODE))	\
+	     : ROUND_ADVANCE (int_size_in_bytes (TYPE))))
+#endif
+
+/* Return boolean indicating arg of mode MODE will be passed in a reg.
+   This macro is only used in this file.  */
+
+#ifdef SPARCV9
+#define PASS_IN_REG_P(CUM, MODE, TYPE)				\
+  (ROUND_REG ((CUM), (MODE)) < NPARM_REGS (MODE)		\
+   && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE)))		\
+   && ((TYPE)==0 || (MODE) != BLKmode))
+#else
+#define PASS_IN_REG_P(CUM, MODE, TYPE)				\
+  ((CUM) < NPARM_REGS (SImode)					\
+   && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE)))		\
+   && ((TYPE)==0 || (MODE) != BLKmode				\
+       || (TYPE_ALIGN (TYPE) % PARM_BOUNDARY == 0)))
+#endif
+
+/* Determine where to put an argument to a function.
+   Value is zero to push the argument on the stack,
+   or a hard register in which to store the argument.
+
+   MODE is the argument's machine mode.
+   TYPE is the data type of the argument (as a tree).
+    This is null for libcalls where that information may
+    not be available.
+   CUM is a variable of type CUMULATIVE_ARGS which gives info about
+    the preceding args and about the function being called.
+   NAMED is nonzero if this argument is a named parameter
+    (otherwise it is an extra parameter matching an ellipsis).  */
+
+/* On SPARC the first six args are normally in registers
+   and the rest are pushed.  Any arg that starts within the first 6 words
+   is at least partially passed in a register unless its data type forbids.
+   For v9, the first 6 int args are passed in regs and the first N
+   float args are passed in regs (where N is such that %f0-15 are filled).
+   The rest are pushed.  Any arg that starts within the first 6 words
+   is at least partially passed in a register unless its data type forbids.  */
+
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)				\
+  (PASS_IN_REG_P ((CUM), (MODE), (TYPE))				\
+   ? gen_rtx (REG, (MODE),						\
+	      (BASE_PASSING_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))))\
+   : 0)
+
+/* Define where a function finds its arguments.
+   This is different from FUNCTION_ARG because of register windows.  */
+
+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED)			\
+  (PASS_IN_REG_P ((CUM), (MODE), (TYPE))				\
+   ? gen_rtx (REG, (MODE),						\
+	      (BASE_INCOMING_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))))\
+   : 0)
+
+/* For an arg passed partly in registers and partly in memory,
+   this is the number of registers used.
+   For args passed entirely in registers or entirely in memory, zero.
+   Any arg that starts in the first 6 regs but won't entirely fit in them
+   needs partial registers on the Sparc (!v9).  On v9, there are no arguments
+   that are passed partially in registers (??? complex values?).  */
+
+#ifndef SPARCV9
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 		\
+  (PASS_IN_REG_P ((CUM), (MODE), (TYPE))				\
+   && ((CUM) + ((MODE) == BLKmode					\
+		? ROUND_ADVANCE (int_size_in_bytes (TYPE))		\
+		: ROUND_ADVANCE (GET_MODE_SIZE (MODE))) - NPARM_REGS (SImode) > 0)\
+   ? (NPARM_REGS (SImode) - (CUM))					\
+   : 0)
+#endif
+
+/* The SPARC ABI stipulates passing struct arguments (of any size) and
+   (!v9) quad-precision floats by invisible reference.
+   For Pascal, also pass arrays by reference.  */
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)		\
+  ((TYPE && (TREE_CODE (TYPE) == RECORD_TYPE				\
+	    || TREE_CODE (TYPE) == UNION_TYPE				\
+    	    || TREE_CODE (TYPE) == ARRAY_TYPE))				\
+   || (!TARGET_V9 && MODE == TFmode))
+
+/* A C expression that indicates when it is the called function's
+   responsibility to make copies of arguments passed by reference.
+   If the callee can determine that the argument won't be modified, it can
+   avoid the copy.  */
+/* ??? We'd love to be able to use NAMED here.  Unfortunately, it doesn't
+   include the last named argument so we keep track of the args ourselves.  */
+
+#ifdef SPARCV9
+#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
+  (sparc_arg_count < sparc_n_named_args)
+#endif
+
+/* Initialize data used by insn expanders.  This is called from
+   init_emit, once for each function, before code is generated.
+   For v9, clear the temp slot used by float/int DImode conversions.
+   ??? There is the 16 bytes at [%fp-16], however we'd like to delete this
+   space at some point.
+   ??? Use assign_stack_temp?  */
+
+extern void sparc64_init_expanders ();
+extern struct rtx_def *sparc64_fpconv_stack_temp ();
+#ifdef SPARCV9
+#define INIT_EXPANDERS sparc64_init_expanders ()
+#endif
+
+/* Define the information needed to generate branch and scc insns.  This is
+   stored from the compare operation.  Note that we can't use "rtx" here
+   since it hasn't been defined!  */
+
+extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1;
+
+/* Define the function that build the compare insn for scc and bcc.  */
+
+extern struct rtx_def *gen_compare_reg ();
+
+/* This function handles all v9 scc insns */
+
+extern int gen_v9_scc ();
+
+/* Generate the special assembly code needed to tell the assembler whatever
+   it might need to know about the return value of a function.
+
+   For Sparc assemblers, we need to output a .proc pseudo-op which conveys
+   information to the assembler relating to peephole optimization (done in
+   the assembler).  */
+
+#define ASM_DECLARE_RESULT(FILE, RESULT) \
+  fprintf ((FILE), "\t.proc\t0%o\n", sparc_type_code (TREE_TYPE (RESULT)))
+
+/* Output the label for a function definition.  */
+
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\
+do {									\
+  ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));			\
+  ASM_OUTPUT_LABEL (FILE, NAME);					\
+} while (0)
+
+/* This macro generates the assembly code for function entry.
+   FILE is a stdio stream to output the code to.
+   SIZE is an int: how many units of temporary storage to allocate.
+   Refer to the array `regs_ever_live' to determine which registers
+   to save; `regs_ever_live[I]' is nonzero if register number I
+   is ever used in the function.  This macro is responsible for
+   knowing which registers should not be saved even if used.  */
+
+/* On SPARC, move-double insns between fpu and cpu need an 8-byte block
+   of memory.  If any fpu reg is used in the function, we allocate
+   such a block here, at the bottom of the frame, just in case it's needed.
+
+   If this function is a leaf procedure, then we may choose not
+   to do a "save" insn.  The decision about whether or not
+   to do this is made in regclass.c.  */
+
+extern int leaf_function;
+#define FUNCTION_PROLOGUE(FILE, SIZE)				\
+  (TARGET_FRW ? sparc_flat_output_function_prologue (FILE, SIZE) \
+   : output_function_prologue (FILE, SIZE, leaf_function))
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+   for profiling a function entry.  */
+
+#define FUNCTION_PROFILER(FILE, LABELNO)  			\
+  do {								\
+    fputs ("\tsethi %hi(", (FILE));				\
+    ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO);		\
+    fputs ("),%o0\n", (FILE));					\
+    if (TARGET_MEDANY)						\
+      fprintf (FILE, "\tadd %%o0,%s,%%o0\n",			\
+	       MEDANY_BASE_REG);				\
+    fputs ("\tcall mcount\n\tadd %lo(", (FILE));		\
+    ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO);		\
+    fputs ("),%o0,%o0\n", (FILE));				\
+  } while (0)
+
+/* Output assembler code to FILE to initialize this source file's
+   basic block profiling info, if that has not already been done.  */
+
+#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO)  \
+  do { \
+    if (TARGET_MEDANY) \
+      fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tor %%0,%%lo(LPBX0),%%o0\n\tld [%s+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%s,%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n", \
+	       MEDANY_BASE_REG, (LABELNO), MEDANY_BASE_REG, (LABELNO)); \
+    else \
+      fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tld [%%lo(LPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%%lo(LPBX0),%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n", \
+	       (LABELNO), (LABELNO)); \
+  } while (0)
+
+/* Output assembler code to FILE to increment the entry-count for
+   the BLOCKNO'th basic block in this source file.  */
+
+#define BLOCK_PROFILER(FILE, BLOCKNO) \
+{ \
+  int blockn = (BLOCKNO); \
+  if (TARGET_MEDANY) \
+    fprintf (FILE, "\tsethi %%hi(LPBX2+%d),%%g1\n\tor %%g1,%%lo(LPBX2+%d),%%g1\n\tld [%%g1+%s],%%g2\n\tadd %%g2,1,%%g2\n\tst %%g2,[%%g1+%s]\n", \
+	     4 * blockn, 4 * blockn, MEDANY_BASE_REG, MEDANY_BASE_REG); \
+  else \
+    fprintf (FILE, "\tsethi %%hi(LPBX2+%d),%%g1\n\tld [%%lo(LPBX2+%d)+%%g1],%%g2\n\
+\tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(LPBX2+%d)+%%g1]\n", \
+	     4 * blockn, 4 * blockn, 4 * blockn); \
+}
+
+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
+   the stack pointer does not matter.  The value is tested only in
+   functions that have frame pointers.
+   No definition is equivalent to always zero.  */
+
+extern int current_function_calls_alloca;
+extern int current_function_outgoing_args_size;
+
+#define EXIT_IGNORE_STACK	\
+ (get_frame_size () != 0	\
+  || current_function_calls_alloca || current_function_outgoing_args_size)
+
+/* This macro generates the assembly code for function exit,
+   on machines that need it.  If FUNCTION_EPILOGUE is not defined
+   then individual return instructions are generated for each
+   return statement.  Args are same as for FUNCTION_PROLOGUE.
+
+   The function epilogue should not depend on the current stack pointer!
+   It should use the frame pointer only.  This is mandatory because
+   of alloca; we also take advantage of it to omit stack adjustments
+   before returning.  */
+
+/* This declaration is needed due to traditional/ANSI
+   incompatibilities which cannot be #ifdefed away
+   because they occur inside of macros.  Sigh.  */
+extern union tree_node *current_function_decl;
+
+#define FUNCTION_EPILOGUE(FILE, SIZE)				\
+  (TARGET_FRW ? sparc_flat_output_function_epilogue (FILE, SIZE) \
+   : output_function_epilogue (FILE, SIZE, leaf_function))
+
+#define DELAY_SLOTS_FOR_EPILOGUE	\
+  (TARGET_FRW ? sparc_flat_epilogue_delay_slots () : 1)
+#define ELIGIBLE_FOR_EPILOGUE_DELAY(trial, slots_filled)	\
+  (TARGET_FRW ? sparc_flat_eligible_for_epilogue_delay (trial, slots_filled) \
+   : eligible_for_epilogue_delay (trial, slots_filled))
+
+/* Output assembler code for a block containing the constant parts
+   of a trampoline, leaving space for the variable parts.  */
+
+/* On the sparc, the trampoline contains five instructions:
+     sethi #TOP_OF_FUNCTION,%g1
+     or #BOTTOM_OF_FUNCTION,%g1,%g1
+     sethi #TOP_OF_STATIC,%g2
+     jmp g1
+     or #BOTTOM_OF_STATIC,%g2,%g2  */
+#define TRAMPOLINE_TEMPLATE(FILE)					\
+{									\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x81C04000));	\
+  ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000));	\
+}
+
+/* Length in units of the trampoline for entering a nested function.  */
+
+#define TRAMPOLINE_SIZE 20
+
+/* Emit RTL insns to initialize the variable parts of a trampoline.
+   FNADDR is an RTX for the address of the function's pure code.
+   CXT is an RTX for the static chain value for the function.  */
+
+void sparc_initialize_trampoline ();
+void sparc64_initialize_trampoline ();
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+  do {								\
+    if (TARGET_V9)						\
+      sparc64_initialize_trampoline (TRAMP, FNADDR, CXT);	\
+    else							\
+      sparc_initialize_trampoline (TRAMP, FNADDR, CXT);		\
+  } while (0)
+
+/* Generate necessary RTL for __builtin_saveregs().
+   ARGLIST is the argument list; see expr.c.  */
+extern struct rtx_def *sparc_builtin_saveregs ();
+#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) sparc_builtin_saveregs (ARGLIST)
+
+/* Generate RTL to flush the register windows so as to make arbitrary frames
+   available.  */
+#define SETUP_FRAME_ADDRESSES()		\
+  emit_insn (gen_flush_register_windows ())
+
+/* Given an rtx for the address of a frame,
+   return an rtx for the address of the word in the frame
+   that holds the dynamic chain--the previous frame's address.
+   ??? -mflat support? */
+#define DYNAMIC_CHAIN_ADDRESS(frame) \
+  gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 14 * UNITS_PER_WORD))
+
+/* The return address isn't on the stack, it is in a register, so we can't
+   access it from the current frame pointer.  We can access it from the
+   previous frame pointer though by reading a value from the register window
+   save area.  */
+#define RETURN_ADDR_IN_PREVIOUS_FRAME
+
+/* The current return address is in %i7.  The return address of anything
+   farther back is in the register window save area at [%fp+60].  */
+/* ??? This ignores the fact that the actual return address is +8 for normal
+   returns, and +12 for structure returns.  */
+#define RETURN_ADDR_RTX(count, frame)		\
+  ((count == -1)				\
+   ? gen_rtx (REG, Pmode, 31)			\
+   : copy_to_reg (gen_rtx (MEM, Pmode,		\
+			   memory_address (Pmode, plus_constant (frame, 15 * UNITS_PER_WORD)))))
+
+/* Addressing modes, and classification of registers for them.  */
+
+/* #define HAVE_POST_INCREMENT */
+/* #define HAVE_POST_DECREMENT */
+
+/* #define HAVE_PRE_DECREMENT */
+/* #define HAVE_PRE_INCREMENT */
+
+/* Macros to check register numbers against specific register classes.  */
+
+/* These assume that REGNO is a hard or pseudo reg number.
+   They give nonzero only if REGNO is a hard reg of the suitable class
+   or a pseudo reg currently allocated to a suitable hard reg.
+   Since they use reg_renumber, they are safe only once reg_renumber
+   has been allocated, which happens in local-alloc.c.  */
+
+#define REGNO_OK_FOR_INDEX_P(REGNO) \
+(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0)
+#define REGNO_OK_FOR_BASE_P(REGNO) \
+(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0)
+#define REGNO_OK_FOR_FP_P(REGNO) \
+  (((unsigned) (REGNO) - 32 < (TARGET_V9 ? 64 : 32)) \
+   || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? 64 : 32)))
+#define REGNO_OK_FOR_CCFP_P(REGNO) \
+ (TARGET_V9 \
+  && ((unsigned) (REGNO) - 96 < 4) || ((unsigned) reg_renumber[REGNO] - 96 < 4))
+
+/* Now macros that check whether X is a register and also,
+   strictly, whether it is in a specified class.
+
+   These macros are specific to the SPARC, and may be used only
+   in code for printing assembler insns and in conditions for
+   define_optimization.  */
+
+/* 1 if X is an fp register.  */
+
+#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))
+
+/* Maximum number of registers that can appear in a valid memory address.  */
+
+#define MAX_REGS_PER_ADDRESS 2
+
+/* Recognize any constant value that is a valid address.
+   When PIC, we do not accept an address that would require a scratch reg
+   to load into a register.  */
+
+#define CONSTANT_ADDRESS_P(X)   \
+  (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF		\
+   || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH			\
+   || (GET_CODE (X) == CONST						\
+       && ! (flag_pic && pic_address_needs_scratch (X))))
+
+/* Define this, so that when PIC, reload won't try to reload invalid
+   addresses which require two reload registers.  */
+
+#define LEGITIMATE_PIC_OPERAND_P(X)  (! pic_address_needs_scratch (X))
+
+/* Nonzero if the constant value X is a legitimate general operand.
+   Anything can be made to work except floating point constants.  */
+
+#define LEGITIMATE_CONSTANT_P(X) \
+  (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode)
+
+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
+   and check its validity for a certain class.
+   We have two alternate definitions for each of them.
+   The usual definition accepts all pseudo regs; the other rejects
+   them unless they have been allocated suitable hard regs.
+   The symbol REG_OK_STRICT causes the latter definition to be used.
+
+   Most source files want to accept pseudo regs in the hope that
+   they will get allocated to the class that the insn wants them to be in.
+   Source files for reload pass need to be strict.
+   After reload, it makes no difference, since pseudo regs have
+   been eliminated by then.  */
+
+/* Optional extra constraints for this machine.  Borrowed from romp.h.
+
+   For the SPARC, `Q' means that this is a memory operand but not a
+   symbolic memory operand.  Note that an unassigned pseudo register
+   is such a memory operand.  Needed because reload will generate
+   these things in insns and then not re-recognize the insns, causing
+   constrain_operands to fail.
+
+   `S' handles constraints for calls.  ??? So where is it?  */
+
+#ifndef REG_OK_STRICT
+
+/* Nonzero if X is a hard reg that can be used as an index
+   or if it is a pseudo reg.  */
+#define REG_OK_FOR_INDEX_P(X) \
+  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32) && REGNO (X) != 0)
+/* Nonzero if X is a hard reg that can be used as a base reg
+   or if it is a pseudo reg.  */
+#define REG_OK_FOR_BASE_P(X) \
+  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32) && REGNO (X) != 0)
+
+/* 'T', 'U' are for aligned memory loads which aren't needed for v9.  */
+
+#define EXTRA_CONSTRAINT(OP, C)				\
+  ((C) == 'Q'						\
+   ? ((GET_CODE (OP) == MEM				\
+       && memory_address_p (GET_MODE (OP), XEXP (OP, 0)) \
+       && ! symbolic_memory_operand (OP, VOIDmode))	\
+      || (reload_in_progress && GET_CODE (OP) == REG	\
+	  && REGNO (OP) >= FIRST_PSEUDO_REGISTER))	\
+   : ! TARGET_V9 && (C) == 'T'			\
+   ? (mem_aligned_8 (OP))				\
+   : ! TARGET_V9 && (C) == 'U'						\
+   ? (register_ok_for_ldd (OP))				\
+   : 0)
+ 
+#else
+
+/* Nonzero if X is a hard reg that can be used as an index.  */
+#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+/* Nonzero if X is a hard reg that can be used as a base reg.  */
+#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+
+#define EXTRA_CONSTRAINT(OP, C)				\
+  ((C) == 'Q'						\
+   ? (GET_CODE (OP) == REG				\
+      ? (REGNO (OP) >= FIRST_PSEUDO_REGISTER		\
+	 && reg_renumber[REGNO (OP)] < 0)		\
+      : GET_CODE (OP) == MEM)				\
+   : ! TARGET_V9 && (C) == 'T'			\
+   ? mem_aligned_8 (OP) && strict_memory_address_p (Pmode, XEXP (OP, 0)) \
+   : ! TARGET_V9 && (C) == 'U'			\
+   ? (GET_CODE (OP) == REG				\
+      && (REGNO (OP) < FIRST_PSEUDO_REGISTER		\
+	  || reg_renumber[REGNO (OP)] > 0)		\
+      && register_ok_for_ldd (OP)) : 0)
+#endif
+
+/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
+   that is a valid memory address for an instruction.
+   The MODE argument is the machine mode for the MEM expression
+   that wants to use this address.
+
+   On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT
+   ordinarily.  This changes a bit when generating PIC.
+
+   If you change this, execute "rm explow.o recog.o reload.o".  */
+
+#define RTX_OK_FOR_BASE_P(X)						\
+  ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))			\
+  || (GET_CODE (X) == SUBREG						\
+      && GET_CODE (SUBREG_REG (X)) == REG				\
+      && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
+
+#define RTX_OK_FOR_INDEX_P(X)						\
+  ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))			\
+  || (GET_CODE (X) == SUBREG						\
+      && GET_CODE (SUBREG_REG (X)) == REG				\
+      && REG_OK_FOR_INDEX_P (SUBREG_REG (X))))
+
+#define RTX_OK_FOR_OFFSET_P(X)						\
+  (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000)
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)		\
+{ if (RTX_OK_FOR_BASE_P (X))				\
+    goto ADDR;						\
+  else if (GET_CODE (X) == PLUS)			\
+    {							\
+      register rtx op0 = XEXP (X, 0);			\
+      register rtx op1 = XEXP (X, 1);			\
+      if (flag_pic && op0 == pic_offset_table_rtx)	\
+	{						\
+	  if (RTX_OK_FOR_BASE_P (op1))			\
+	    goto ADDR;					\
+	  else if (flag_pic == 1			\
+		   && GET_CODE (op1) != REG		\
+		   && GET_CODE (op1) != LO_SUM		\
+		   && GET_CODE (op1) != MEM		\
+		   && (GET_CODE (op1) != CONST_INT	\
+		       || SMALL_INT (op1)))		\
+	    goto ADDR;					\
+	}						\
+      else if (RTX_OK_FOR_BASE_P (op0))			\
+	{						\
+	  if (RTX_OK_FOR_INDEX_P (op1)			\
+	      || RTX_OK_FOR_OFFSET_P (op1))		\
+	    goto ADDR;					\
+	}						\
+      else if (RTX_OK_FOR_BASE_P (op1))			\
+	{						\
+	  if (RTX_OK_FOR_INDEX_P (op0)			\
+	      || RTX_OK_FOR_OFFSET_P (op0))		\
+	    goto ADDR;					\
+	}						\
+    }							\
+  else if (GET_CODE (X) == LO_SUM)			\
+    {							\
+      register rtx op0 = XEXP (X, 0);			\
+      register rtx op1 = XEXP (X, 1);			\
+      if (RTX_OK_FOR_BASE_P (op0)			\
+	  && CONSTANT_P (op1)				\
+	  /* We can't allow TFmode, because an offset	\
+	     greater than or equal to the alignment (8)	\
+	     may cause the LO_SUM to overflow.  */	\
+	  && MODE != TFmode)				\
+	goto ADDR;					\
+    }							\
+  else if (GET_CODE (X) == CONST_INT && SMALL_INT (X))	\
+    goto ADDR;						\
+}
+
+/* Try machine-dependent ways of modifying an illegitimate address
+   to be legitimate.  If we find one, return the new, valid address.
+   This macro is used in only one place: `memory_address' in explow.c.
+
+   OLDX is the address as it was before break_out_memory_refs was called.
+   In some cases it is useful to look at this to decide what needs to be done.
+
+   MODE and WIN are passed so that this macro can use
+   GO_IF_LEGITIMATE_ADDRESS.
+
+   It is always safe for this macro to do nothing.  It exists to recognize
+   opportunities to optimize the output.  */
+
+/* On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG.  */
+extern struct rtx_def *legitimize_pic_address ();
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)	\
+{ rtx sparc_x = (X);						\
+  if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT)	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 1),			\
+		   force_operand (XEXP (X, 0), NULL_RTX));	\
+  if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT)	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0),			\
+		   force_operand (XEXP (X, 1), NULL_RTX));	\
+  if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == PLUS)	\
+    (X) = gen_rtx (PLUS, Pmode, force_operand (XEXP (X, 0), NULL_RTX),\
+		   XEXP (X, 1));				\
+  if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == PLUS)	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0),			\
+		   force_operand (XEXP (X, 1), NULL_RTX));	\
+  if (sparc_x != (X) && memory_address_p (MODE, X))		\
+    goto WIN;							\
+  if (flag_pic) (X) = legitimize_pic_address (X, MODE, 0);	\
+  else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1)))	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0),			\
+		   copy_to_mode_reg (Pmode, XEXP (X, 1)));	\
+  else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0)))	\
+    (X) = gen_rtx (PLUS, Pmode, XEXP (X, 1),			\
+		   copy_to_mode_reg (Pmode, XEXP (X, 0)));	\
+  else if (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST	\
+	   || GET_CODE (X) == LABEL_REF)			\
+    (X) = gen_rtx (LO_SUM, Pmode,				\
+		   copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, X)), X); \
+  if (memory_address_p (MODE, X))				\
+    goto WIN; }
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+   has an effect that depends on the machine mode it is used for.
+   On the SPARC this is never true.  */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
+
+/* If we are referencing a function make the SYMBOL_REF special.
+   In the Medium/Anywhere code model, %g4 points to the data segment so we
+   must not add it to function addresses.  */
+
+#define ENCODE_SECTION_INFO(DECL) \
+  do {							\
+    if (TARGET_MEDANY && TREE_CODE (DECL) == FUNCTION_DECL) \
+      SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;	\
+  } while (0)
+
+/* Specify the machine mode that this machine uses
+   for the index in the tablejump instruction.  */
+#define CASE_VECTOR_MODE Pmode
+
+/* Define this if the tablejump instruction expects the table
+   to contain offsets from the address of the table.
+   Do not define this if the table should contain absolute addresses.  */
+/* #define CASE_VECTOR_PC_RELATIVE */
+
+/* Specify the tree operation to be used to convert reals to integers.  */
+#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+
+/* This is the kind of divide that is easiest to do in the general case.  */
+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
+
+/* Define this as 1 if `char' should by default be signed; else as 0.  */
+#define DEFAULT_SIGNED_CHAR 1
+
+/* Max number of bytes we can move from memory to memory
+   in one reasonably fast instruction.  */
+#define MOVE_MAX 8
+
+#if 0 /* Sun 4 has matherr, so this is no good.  */
+/* This is the value of the error code EDOM for this machine,
+   used by the sqrt instruction.  */
+#define TARGET_EDOM 33
+
+/* This is how to refer to the variable errno.  */
+#define GEN_ERRNO_RTX \
+  gen_rtx (MEM, SImode, gen_rtx (SYMBOL_REF, Pmode, "errno"))
+#endif /* 0 */
+
+/* Define if operations between registers always perform the operation
+   on the full register even if a narrower mode is specified.  */
+#define WORD_REGISTER_OPERATIONS
+
+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
+   will either zero-extend or sign-extend.  The value of this macro should
+   be the code that says which one of the two operations is implicitly
+   done, NIL if none.  */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* Nonzero if access to memory by bytes is slow and undesirable.
+   For RISC chips, it means that access to memory by bytes is no
+   better than access by words when possible, so grab a whole word
+   and maybe make use of that.  */
+#define SLOW_BYTE_ACCESS 1
+
+/* We assume that the store-condition-codes instructions store 0 for false
+   and some other value for true.  This is the value stored for true.  */
+
+#define STORE_FLAG_VALUE 1
+
+/* When a prototype says `char' or `short', really pass an `int'.  */
+#define PROMOTE_PROTOTYPES
+
+/* Define this to be nonzero if shift instructions ignore all but the low-order
+   few bits. */
+#define SHIFT_COUNT_TRUNCATED 1
+
+/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
+   is done just by pretending it is already truncated.  */
+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+
+/* Specify the machine mode that pointers have.
+   After generation of rtl, the compiler makes no further distinction
+   between pointers and any other objects of this machine mode.  */
+#define Pmode (TARGET_PTR64 ? DImode : SImode)
+
+/* Generate calls to memcpy, memcmp and memset.  */
+#define TARGET_MEM_FUNCTIONS
+
+/* Add any extra modes needed to represent the condition code.
+
+   On the Sparc, we have a "no-overflow" mode which is used when an add or
+   subtract insn is used to set the condition code.  Different branches are
+   used in this case for some operations.
+
+   We also have two modes to indicate that the relevant condition code is
+   in the floating-point condition code register.  One for comparisons which
+   will generate an exception if the result is unordered (CCFPEmode) and
+   one for comparisons which will never trap (CCFPmode).  This really should
+   be a separate register, but we don't want to go to 65 registers.
+
+   CCXmode and CCX_NOOVmode are only used by v9.  */
+
+#define EXTRA_CC_MODES CCXmode, CC_NOOVmode, CCX_NOOVmode, CCFPmode, CCFPEmode
+
+/* Define the names for the modes specified above.  */
+
+#define EXTRA_CC_NAMES "CCX", "CC_NOOV", "CCX_NOOV", "CCFP", "CCFPE"
+
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
+   return the mode to be used for the comparison.  For floating-point,
+   CCFP[E]mode is used.  CC_NOOVmode should be used when the first operand is a
+   PLUS, MINUS, NEG, or ASHIFT.  CCmode should be used when no special
+   processing is needed.  */
+#define SELECT_CC_MODE(OP,X,Y) \
+  (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT				\
+   ? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode)			\
+   : ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS			\
+       || GET_CODE (X) == NEG || GET_CODE (X) == ASHIFT)		\
+      ? (TARGET_V9 && GET_MODE (X) == DImode ? CCX_NOOVmode : CC_NOOVmode) \
+      : (TARGET_V9 && GET_MODE (X) == DImode ? CCXmode : CCmode)))
+
+/* Return non-zero if SELECT_CC_MODE will never return MODE for a
+   floating point inequality comparison.  */
+
+#define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode)
+
+/* A function address in a call instruction
+   is a byte address (for indexing purposes)
+   so give the MEM rtx a byte's mode.  */
+#define FUNCTION_MODE SImode
+
+/* Define this if addresses of constant functions
+   shouldn't be put through pseudo regs where they can be cse'd.
+   Desirable on machines where ordinary constants are expensive
+   but a CALL with constant address is cheap.  */
+#define NO_FUNCTION_CSE
+
+/* alloca should avoid clobbering the old register save area.  */
+#define SETJMP_VIA_SAVE_AREA
+
+/* Define subroutines to call to handle multiply and divide.
+   Use the subroutines that Sun's library provides.
+   The `*' prevents an underscore from being prepended by the compiler.  */
+
+#define DIVSI3_LIBCALL "*.div"
+#define UDIVSI3_LIBCALL "*.udiv"
+#define MODSI3_LIBCALL "*.rem"
+#define UMODSI3_LIBCALL "*.urem"
+/* .umul is a little faster than .mul.  */
+#define MULSI3_LIBCALL "*.umul"
+
+/* Define library calls for quad FP operations.  These are all part of the
+   SPARC ABI.  */
+#define ADDTF3_LIBCALL "_Q_add"
+#define SUBTF3_LIBCALL "_Q_sub"
+#define NEGTF2_LIBCALL "_Q_neg"
+#define MULTF3_LIBCALL "_Q_mul"
+#define DIVTF3_LIBCALL "_Q_div"
+#define FLOATSITF2_LIBCALL "_Q_itoq"
+#define FIX_TRUNCTFSI2_LIBCALL "_Q_qtoi"
+#define FIXUNS_TRUNCTFSI2_LIBCALL "_Q_qtou"
+#define EXTENDSFTF2_LIBCALL "_Q_stoq"
+#define TRUNCTFSF2_LIBCALL "_Q_qtos"
+#define EXTENDDFTF2_LIBCALL "_Q_dtoq"
+#define TRUNCTFDF2_LIBCALL "_Q_qtod"
+#define EQTF2_LIBCALL "_Q_feq"
+#define NETF2_LIBCALL "_Q_fne"
+#define GTTF2_LIBCALL "_Q_fgt"
+#define GETF2_LIBCALL "_Q_fge"
+#define LTTF2_LIBCALL "_Q_flt"
+#define LETF2_LIBCALL "_Q_fle"
+
+/* We can define the TFmode sqrt optab only if TARGET_FPU.  This is because
+   with soft-float, the SFmode and DFmode sqrt instructions will be absent,
+   and the compiler will notice and try to use the TFmode sqrt instruction
+   for calls to the builtin function sqrt, but this fails.  */
+#define INIT_TARGET_OPTABS						\
+  do {									\
+    add_optab->handlers[(int) TFmode].libfunc				\
+      = gen_rtx (SYMBOL_REF, Pmode, ADDTF3_LIBCALL);			\
+    sub_optab->handlers[(int) TFmode].libfunc				\
+      = gen_rtx (SYMBOL_REF, Pmode, SUBTF3_LIBCALL);			\
+    neg_optab->handlers[(int) TFmode].libfunc				\
+      = gen_rtx (SYMBOL_REF, Pmode, NEGTF2_LIBCALL);			\
+    smul_optab->handlers[(int) TFmode].libfunc				\
+      = gen_rtx (SYMBOL_REF, Pmode, MULTF3_LIBCALL);			\
+    flodiv_optab->handlers[(int) TFmode].libfunc			\
+      = gen_rtx (SYMBOL_REF, Pmode, DIVTF3_LIBCALL);			\
+    eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EQTF2_LIBCALL);		\
+    netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, NETF2_LIBCALL);		\
+    gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GTTF2_LIBCALL);		\
+    getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GETF2_LIBCALL);		\
+    lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LTTF2_LIBCALL);		\
+    letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LETF2_LIBCALL);		\
+    trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFSF2_LIBCALL);   \
+    trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFDF2_LIBCALL);   \
+    extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDSFTF2_LIBCALL); \
+    extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDDFTF2_LIBCALL); \
+    floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, FLOATSITF2_LIBCALL);    \
+    fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIX_TRUNCTFSI2_LIBCALL);  \
+    fixunstfsi_libfunc							\
+      = gen_rtx (SYMBOL_REF, Pmode, FIXUNS_TRUNCTFSI2_LIBCALL);		\
+    if (TARGET_FPU)							\
+      sqrt_optab->handlers[(int) TFmode].libfunc			\
+	= gen_rtx (SYMBOL_REF, Pmode, "_Q_sqrt");			\
+    INIT_SUBTARGET_OPTABS;						\
+  } while (0)
+
+/* This is meant to be redefined in the host dependent files */
+#define INIT_SUBTARGET_OPTABS
+
+/* Compute the cost of computing a constant rtl expression RTX
+   whose rtx-code is CODE.  The body of this macro is a portion
+   of a switch statement.  If the code is computed here,
+   return it with a return statement.  Otherwise, break from the switch.  */
+
+#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
+  case CONST_INT:						\
+    if (INTVAL (RTX) < 0x1000 && INTVAL (RTX) >= -0x1000)	\
+      return 0;							\
+  case HIGH:							\
+    return 2;							\
+  case CONST:							\
+  case LABEL_REF:						\
+  case SYMBOL_REF:						\
+    return 4;							\
+  case CONST_DOUBLE:						\
+    if (GET_MODE (RTX) == DImode)				\
+      if ((XINT (RTX, 3) == 0					\
+	   && (unsigned) XINT (RTX, 2) < 0x1000)		\
+	  || (XINT (RTX, 3) == -1				\
+	      && XINT (RTX, 2) < 0				\
+	      && XINT (RTX, 2) >= -0x1000))			\
+	return 0;						\
+    return 8;
+
+/* Compute the cost of an address.  For the sparc, all valid addresses are
+   the same cost.
+   ??? Is this true for v9?  */
+
+#define ADDRESS_COST(RTX)  1
+
+/* Compute extra cost of moving data between one register class
+   and another.
+   ??? v9: We ignore FPCC_REGS on the assumption they'll never be seen.  */
+#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
+  (((FP_REG_CLASS_P (CLASS1) && (CLASS2) == GENERAL_REGS) \
+    || ((CLASS1) == GENERAL_REGS && FP_REG_CLASS_P (CLASS2))) ? 6 : 2)
+
+/* Provide the costs of a rtl expression.  This is in the body of a
+   switch on CODE.  The purpose for the cost of MULT is to encourage
+   `synth_mult' to find a synthetic multiply when reasonable.
+
+   If we need more than 12 insns to do a multiply, then go out-of-line,
+   since the call overhead will be < 10% of the cost of the multiply.  */
+
+#define RTX_COSTS(X,CODE,OUTER_CODE)			\
+  case MULT:						\
+    return (TARGET_V8 || TARGET_V9) ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25);	\
+  case DIV:						\
+  case UDIV:						\
+  case MOD:						\
+  case UMOD:						\
+    return COSTS_N_INSNS (25);				\
+  /* Make FLOAT and FIX more expensive than CONST_DOUBLE,\
+     so that cse will favor the latter.  */		\
+  case FLOAT:						\
+  case FIX:						\
+    return 19;
+
+/* Adjust the cost of dependencies.  */
+#define ADJUST_COST(INSN,LINK,DEP,COST) \
+  if (TARGET_SUPERSPARC) \
+  (COST) = supersparc_adjust_cost (INSN, LINK, DEP, COST)
+
+/* Conditional branches with empty delay slots have a length of two.  */
+#define ADJUST_INSN_LENGTH(INSN, LENGTH)	\
+  if (GET_CODE (INSN) == CALL_INSN					\
+      || (GET_CODE (INSN) == JUMP_INSN && ! simplejump_p (insn)))	\
+    LENGTH += 1;
+
+/* Control the assembler format that we output.  */
+
+/* Output at beginning of assembler file.  */
+
+#define ASM_FILE_START(file)
+
+/* Output to assembler file text saying following lines
+   may contain character constants, extra white space, comments, etc.  */
+
+#define ASM_APP_ON ""
+
+/* Output to assembler file text saying following lines
+   no longer contain unusual constructs.  */
+
+#define ASM_APP_OFF ""
+
+/* ??? Try to make the style consistent here (_OP?).  */
+
+#define ASM_LONGLONG	".xword"
+#define ASM_LONG	".word"
+#define ASM_SHORT	".half"
+#define ASM_BYTE_OP	".byte"
+#define ASM_FLOAT	".single"
+#define ASM_DOUBLE	".double"
+#define ASM_LONGDOUBLE	".xxx"		/* ??? Not known (or used yet). */
+
+/* Output before read-only data.  */
+
+#define TEXT_SECTION_ASM_OP ".text"
+
+/* Output before writable data.  */
+
+#define DATA_SECTION_ASM_OP ".data"
+
+/* How to refer to registers in assembler output.
+   This sequence is indexed by compiler's hard-register-number (see above).  */
+
+#ifdef SPARCV9
+#define REGISTER_NAMES \
+{"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",		\
+ "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",		\
+ "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",		\
+ "%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",		\
+ "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",		\
+ "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",		\
+ "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",	\
+ "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",	\
+ "%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",	\
+ "%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",	\
+ "%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",	\
+ "%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",	\
+ "%fcc0", "%fcc1", "%fcc2", "%fcc3"}
+#else
+#define REGISTER_NAMES \
+{"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",		\
+ "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",		\
+ "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",		\
+ "%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",		\
+ "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",		\
+ "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",		\
+ "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",	\
+ "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31"}
+#endif
+
+/* Define additional names for use in asm clobbers and asm declarations.
+
+   We define the fake Condition Code register as an alias for reg 0 (which
+   is our `condition code' register), so that condition codes can easily
+   be clobbered by an asm.  No such register actually exists.  Condition
+   codes are partly stored in the PSR and partly in the FSR.  */
+
+#define ADDITIONAL_REGISTER_NAMES	{"ccr", 0, "cc", 0}
+
+/* How to renumber registers for dbx and gdb.  */
+
+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+/* On Sun 4, this limit is 2048.  We use 1500 to be safe,
+   since the length can run past this up to a continuation point.  */
+#define DBX_CONTIN_LENGTH 1500
+
+/* This is how to output a note to DBX telling it the line number
+   to which the following sequence of instructions corresponds.
+
+   This is needed for SunOS 4.0, and should not hurt for 3.2
+   versions either.  */
+#define ASM_OUTPUT_SOURCE_LINE(file, line)		\
+  { static int sym_lineno = 1;				\
+    fprintf (file, ".stabn 68,0,%d,LM%d\nLM%d:\n",	\
+	     line, sym_lineno, sym_lineno);		\
+    sym_lineno += 1; }
+
+/* This is how to output the definition of a user-level label named NAME,
+   such as the label on a static function or variable NAME.  */
+
+#define ASM_OUTPUT_LABEL(FILE,NAME)	\
+  do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
+
+/* This is how to output a command to make the user-level label named NAME
+   defined for reference from other files.  */
+
+#define ASM_GLOBALIZE_LABEL(FILE,NAME)	\
+  do { fputs ("\t.global ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+
+/* This is how to output a reference to a user-level label named NAME.
+   `assemble_name' uses this.  */
+
+#define ASM_OUTPUT_LABELREF(FILE,NAME)	\
+  fprintf (FILE, "_%s", NAME)
+
+/* This is how to output a definition of an internal numbered label where
+   PREFIX is the class of label and NUM is the number within the class.  */
+
+#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)	\
+  fprintf (FILE, "%s%d:\n", PREFIX, NUM)
+
+/* This is how to output a reference to an internal numbered label where
+   PREFIX is the class of label and NUM is the number within the class.  */
+/* FIXME:  This should be used throughout gcc, and documented in the texinfo
+   files.  There is no reason you should have to allocate a buffer and
+   `sprintf' to reference an internal label (as opposed to defining it).  */
+
+#define ASM_OUTPUT_INTERNAL_LABELREF(FILE,PREFIX,NUM)	\
+  fprintf (FILE, "%s%d", PREFIX, NUM)
+
+/* This is how to store into the string LABEL
+   the symbol_ref name of an internal numbered label where
+   PREFIX is the class of label and NUM is the number within the class.
+   This is suitable for output with `assemble_name'.  */
+
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
+  sprintf (LABEL, "*%s%d", PREFIX, NUM)
+
+/* This is how to output an assembler line defining a `double' constant.  */
+
+#define ASM_OUTPUT_DOUBLE(FILE,VALUE)					\
+  {									\
+    long t[2];								\
+    REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);				\
+    fprintf (FILE, "\t%s\t0x%lx\n\t%s\t0x%lx\n",			\
+	     ASM_LONG, t[0], ASM_LONG, t[1]);				\
+  }
+
+/* This is how to output an assembler line defining a `float' constant.  */
+
+#define ASM_OUTPUT_FLOAT(FILE,VALUE)					\
+  {									\
+    long t;								\
+    REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);				\
+    fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t);			\
+  }									\
+
+/* This is how to output an assembler line defining a `long double'
+   constant.  */
+
+#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)				\
+  {									\
+    long t[4];								\
+    REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), t);			\
+    fprintf (FILE, "\t%s\t0x%lx\n\t%s\t0x%lx\n\t%s\t0x%lx\n\t%s\t0x%lx\n", \
+      ASM_LONG, t[0], ASM_LONG, t[1], ASM_LONG, t[2], ASM_LONG, t[3]);	\
+  }
+
+/* This is how to output an assembler line defining an `int' constant.  */
+
+#define ASM_OUTPUT_INT(FILE,VALUE)  \
+( fprintf (FILE, "\t%s\t", ASM_LONG),		\
+  output_addr_const (FILE, (VALUE)),		\
+  fprintf (FILE, "\n"))
+
+/* This is how to output an assembler line defining a DImode constant.  */
+#define ASM_OUTPUT_DOUBLE_INT(FILE,VALUE)  \
+  output_double_int (FILE, VALUE)
+
+/* Likewise for `char' and `short' constants.  */
+
+#define ASM_OUTPUT_SHORT(FILE,VALUE)  \
+( fprintf (FILE, "\t%s\t", ASM_SHORT),		\
+  output_addr_const (FILE, (VALUE)),		\
+  fprintf (FILE, "\n"))
+
+#define ASM_OUTPUT_CHAR(FILE,VALUE)  \
+( fprintf (FILE, "\t%s\t", ASM_BYTE_OP),	\
+  output_addr_const (FILE, (VALUE)),		\
+  fprintf (FILE, "\n"))
+
+/* This is how to output an assembler line for a numeric constant byte.  */
+
+#define ASM_OUTPUT_BYTE(FILE,VALUE)  \
+  fprintf (FILE, "\t%s\t0x%x\n", ASM_BYTE_OP, (VALUE))
+
+/* This is how to output an element of a case-vector that is absolute.  */
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
+do {									\
+  char label[30];							\
+  ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);			\
+  if (Pmode == SImode)							\
+    fprintf (FILE, "\t.word\t");					\
+  else if (TARGET_ENV32)						\
+    fprintf (FILE, "\t.word\t0\n\t.word\t");				\
+  else									\
+    fprintf (FILE, "\t.xword\t");					\
+  assemble_name (FILE, label);						\
+  fprintf (FILE, "\n");							\
+} while (0)
+
+/* This is how to output an element of a case-vector that is relative.
+   (SPARC uses such vectors only when generating PIC.)  */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)			\
+do {									\
+  char label[30];							\
+  ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);			\
+  if (Pmode == SImode)							\
+    fprintf (FILE, "\t.word\t");					\
+  else if (TARGET_ENV32)						\
+    fprintf (FILE, "\t.word\t0\n\t.word\t");				\
+  else									\
+    fprintf (FILE, "\t.xword\t");					\
+  assemble_name (FILE, label);						\
+  fprintf (FILE, "-1b\n");						\
+} while (0)
+
+/* This is how to output an assembler line
+   that says to advance the location counter
+   to a multiple of 2**LOG bytes.  */
+
+#define ASM_OUTPUT_ALIGN(FILE,LOG)	\
+  if ((LOG) != 0)			\
+    fprintf (FILE, "\t.align %d\n", (1<<(LOG)))
+
+#define ASM_OUTPUT_SKIP(FILE,SIZE)  \
+  fprintf (FILE, "\t.skip %u\n", (SIZE))
+
+/* This says how to output an assembler line
+   to define a global common symbol.  */
+
+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
+( fputs ("\t.common ", (FILE)),		\
+  assemble_name ((FILE), (NAME)),		\
+  fprintf ((FILE), ",%u,\"bss\"\n", (SIZE)))
+
+/* This says how to output an assembler line to define a local common
+   symbol.  */
+
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED)		\
+( fputs ("\t.reserve ", (FILE)),					\
+  assemble_name ((FILE), (NAME)),					\
+  fprintf ((FILE), ",%u,\"bss\",%u\n",					\
+	   (SIZE), ((ALIGNED) / BITS_PER_UNIT)))
+
+/* Store in OUTPUT a string (made with alloca) containing
+   an assembler-name for a local static variable named NAME.
+   LABELNO is an integer which is different for each call.  */
+
+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)	\
+( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),	\
+  sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+
+#define IDENT_ASM_OP ".ident"
+
+/* Output #ident as a .ident.  */
+
+#define ASM_OUTPUT_IDENT(FILE, NAME) \
+  fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME);
+
+/* Define the parentheses used to group arithmetic operations
+   in assembler code.  */
+
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* Define results of standard character escape sequences.  */
+#define TARGET_BELL 007
+#define TARGET_BS 010
+#define TARGET_TAB 011
+#define TARGET_NEWLINE 012
+#define TARGET_VT 013
+#define TARGET_FF 014
+#define TARGET_CR 015
+
+#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
+  ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(')
+
+/* Print operand X (an rtx) in assembler syntax to file FILE.
+   CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
+   For `%' followed by punctuation, CODE is the punctuation and X is null.  */
+
+#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
+
+/* Print a memory address as an operand to reference that memory location.  */
+
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
+{ register rtx base, index = 0;					\
+  int offset = 0;						\
+  register rtx addr = ADDR;					\
+  if (GET_CODE (addr) == REG)					\
+    fputs (reg_names[REGNO (addr)], FILE);			\
+  else if (GET_CODE (addr) == PLUS)				\
+    {								\
+      if (GET_CODE (XEXP (addr, 0)) == CONST_INT)		\
+	offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);\
+      else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)		\
+	offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\
+      else							\
+	base = XEXP (addr, 0), index = XEXP (addr, 1);		\
+      fputs (reg_names[REGNO (base)], FILE);			\
+      if (index == 0)						\
+	fprintf (FILE, "%+d", offset);				\
+      else if (GET_CODE (index) == REG)				\
+	fprintf (FILE, "+%s", reg_names[REGNO (index)]);	\
+      else if (GET_CODE (index) == SYMBOL_REF)			\
+	fputc ('+', FILE), output_addr_const (FILE, index);	\
+      else abort ();						\
+    }								\
+  else if (GET_CODE (addr) == MINUS				\
+	   && GET_CODE (XEXP (addr, 1)) == LABEL_REF)		\
+    {								\
+      output_addr_const (FILE, XEXP (addr, 0));			\
+      fputs ("-(", FILE);					\
+      output_addr_const (FILE, XEXP (addr, 1));			\
+      fputs ("-.)", FILE);					\
+    }								\
+  else if (GET_CODE (addr) == LO_SUM)				\
+    {								\
+      output_operand (XEXP (addr, 0), 0);			\
+      fputs ("+%lo(", FILE);					\
+      output_address (XEXP (addr, 1));				\
+      fputc (')', FILE);					\
+    }								\
+  else if (flag_pic && GET_CODE (addr) == CONST			\
+	   && GET_CODE (XEXP (addr, 0)) == MINUS		\
+	   && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST	\
+	   && GET_CODE (XEXP (XEXP (XEXP (addr, 0), 1), 0)) == MINUS	\
+	   && XEXP (XEXP (XEXP (XEXP (addr, 0), 1), 0), 1) == pc_rtx)	\
+    {								\
+      addr = XEXP (addr, 0);					\
+      output_addr_const (FILE, XEXP (addr, 0));			\
+      /* Group the args of the second CONST in parenthesis.  */	\
+      fputs ("-(", FILE);					\
+      /* Skip past the second CONST--it does nothing for us.  */\
+      output_addr_const (FILE, XEXP (XEXP (addr, 1), 0));	\
+      /* Close the parenthesis.  */				\
+      fputc (')', FILE);					\
+    }								\
+  else								\
+    {								\
+      output_addr_const (FILE, addr);				\
+    }								\
+}
+
+/* Declare functions defined in sparc.c and used in templates.  */
+
+extern char *singlemove_string ();
+extern char *output_move_double ();
+extern char *output_move_quad ();
+extern char *output_fp_move_double ();
+extern char *output_fp_move_quad ();
+extern char *output_block_move ();
+extern char *output_scc_insn ();
+extern char *output_cbranch ();
+extern char *output_v9branch ();
+extern char *output_return ();
+
+/* Defined in flags.h, but insn-emit.c does not include flags.h.  */
+
+extern int flag_pic;
--- libc-sparc-5.3.12.orig/libc/gcc/config/sparc/xm-linux.h
+++ libc-sparc-5.3.12/libc/gcc/config/sparc/xm-linux.h
@@ -0,0 +1,30 @@
+/* Configuration for GCC for Intel i386 running Linux.
+   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+   Contributed by H.J. Lu (hjl@nynexst.com)
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "sparc/xm-sparc.h"
+#include "xm-svr3.h"
+
+#undef BSTRING
+#define BSTRING
+#undef bcmp
+#undef bcopy
+#undef bzero
+#undef index
+#undef rindex
--- libc-sparc-5.3.12.orig/libc/gcc/config/sparc/xm-sparc.h
+++ libc-sparc-5.3.12/libc/gcc/config/sparc/xm-sparc.h
@@ -0,0 +1,49 @@
+/* Configuration for GNU C-compiler for Sun Sparc.
+   Copyright (C) 1988, 1993 Free Software Foundation, Inc.
+   Contributed by Michael Tiemann (tiemann@cygnus.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+
+/* #defines that need visibility everywhere.  */
+#define FALSE 0
+#define TRUE 1
+
+/* This describes the machine the compiler is hosted on.  */
+#define HOST_BITS_PER_CHAR 8
+#define HOST_BITS_PER_SHORT 16
+#define HOST_BITS_PER_INT 32
+#define HOST_BITS_PER_LONG 32
+#define HOST_BITS_PER_LONGLONG 64
+
+/* Doubles are stored in memory with the high order word first.  This
+   matters when cross-compiling.  */
+#define HOST_WORDS_BIG_ENDIAN 1
+
+/* target machine dependencies.
+   tm.h is a symbolic link to the actual target specific file.   */
+#include "tm.h"
+
+/* Arguments to use with `exit'.  */
+#define SUCCESS_EXIT_CODE 0
+#define FATAL_EXIT_CODE 33
+
+/* If compiled with Sun CC, the use of alloca requires this #include.  */
+#ifndef __GNUC__
+#include "alloca.h"
+#endif
--- libc-sparc-5.3.12.orig/libc/gcc/config/xm-svr3.h
+++ libc-sparc-5.3.12/libc/gcc/config/xm-svr3.h
@@ -0,0 +1,32 @@
+/* Configuration for GNU C-compiler for hosts running System V Release 3
+   Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define bcopy(src,dst,len) memcpy ((dst),(src),(len))
+#define bzero(dst,len) memset ((dst),0,(len))
+#define bcmp(left,right,len) memcmp ((left),(right),(len))
+
+#define rindex strrchr
+#define index strchr
+
+#define USG
+#define HAVE_VPRINTF
+
+#ifndef SVR3
+#define SVR3
+#endif
--- libc-sparc-5.3.12.orig/libc/gcc/Makefile
+++ libc-sparc-5.3.12/libc/gcc/Makefile
@@ -124,6 +124,19 @@
 
 endif
 
+config.h: config/sparc/xm-linux.h
+	ln -s $? $@
+
+hconfig.h: config/sparc/xm-linux.h
+	ln -s $? $@
+
+tconfig.h: config/sparc/xm-linux.h
+	ln -s $? $@
+
+tm.h: config/sparc/linux.h
+	ln -s $? $@
+
+
 ifeq ($(CANONICAL_TARGET_MACHINE),m68k-linux)
 
 config.h: config/m68k/xm-linux.h
--- libc-sparc-5.3.12.orig/libc/inet/gethstnmad.c
+++ libc-sparc-5.3.12/libc/inet/gethstnmad.c
@@ -206,7 +206,13 @@
 /* Hal Stern (June 1992) of Sun claimed that more than 4 ethernets in a
 Sun 4/690 would not work.  This variable is set to 10 to accomodate our
 version of reality */
-#define MAXINTERFACES (10)
+/* What a complete billgatesism. Lets have 256. Better yet lets rant
+   at whichever plonker made this static and fix it nicely
+   
+   		Alan [Dreaming of glibc]
+   		*/
+   		
+#define MAXINTERFACES (512)	/* 	Well I know someone with over 256 */
 
 static void reorder_addrs(h)
 struct hostent *h;
@@ -250,7 +256,8 @@
 		endp = ifs.ifc_len / sizeof(struct ifreq);
 		itp = itab;
 		for (p = ifs.ifc_req; endp; p++, endp--) {
-			strcpy( itp->iname , p->ifr_name); /* copy interface name */
+			strncpy( itp->iname , p->ifr_name,
+				sizeof(itp->iname)); /* copy interface name */
 
 			err = ioctl(fd, SIOCGIFNETMASK, p); /* get netmask */
             if (err == -1) continue;	/* error? skip this interface */
@@ -302,11 +309,12 @@
 	FILE *fd;
 	char *tdp = trimdomainbuf;
 	char *hostconf;
+	int tdproom=sizeof(trimdomainbuf)-1;
 
 #if NLS
 	libc_nls_init();
 #endif
-	if(NULL==(hostconf=getenv(ENV_HOSTCONF))){
+	if(NULL==(hostconf=__libc_secure_getenv(ENV_HOSTCONF))){
 		hostconf=_PATH_HOSTCONF;
 	}
 	if ((fd = (FILE *)fopen(hostconf, "r")) == NULL) {
@@ -477,9 +485,14 @@
 					while (*cp == ' ' || *cp == '\t') cp++;
                                         if (*cp)
                                         {
-                                            (void) strcpy(tdp,cp);
-                                            trimdomain[numtrimdomains++]=tdp;
-                                            tdp += strlen(cp)+1;
+                                            int sl=strlen(cp)+1;
+                                            if(tdproom>sl)
+                                            {
+                                            	(void) strcpy(tdp,cp);
+                                            	trimdomain[numtrimdomains++]=tdp;
+                                            	tdp += sl;
+                                            	tdproom -= sl;
+                                            }
                                         } else
                                             bad_config_format(CMD_TRIMDOMAIN);
                                     } else
@@ -504,7 +517,7 @@
 		fclose(fd);
 	}
 	/* override service_order if environment variable */
-	if(NULL!=(cp=getenv(ENV_SERVORDER))){
+	if(NULL!=(cp=__libc_secure_getenv(ENV_SERVORDER))){
 		cc=0;
 		if(NULL!=(cp=strtok(cp, TOKEN_SEPARATORS))){
 			do{
@@ -521,7 +534,7 @@
 		}
 	}
 	/* override spoof if environment variable */
-	if(NULL!=(cp=getenv(ENV_SPOOF))){
+	if(NULL!=(cp=__libc_secure_getenv(ENV_SPOOF))){
 		if(checkbuf(cp, CMD_WARN)){
 			spoof=1;
 			spoofalert=1;
@@ -537,21 +550,21 @@
 	}
 
 	/* override hma if environment variable */
-	if(NULL!=(cp=getenv(ENV_HMA)))
+	if(NULL!=(cp=__libc_secure_getenv(ENV_HMA)))
 		if(checkbuf(cp, CMD_ON))
 			hosts_multiple_addrs=1;
 		else
 			hosts_multiple_addrs=0;
 
 	/* override reorder if environment variable */
-	if ((cp = getenv(ENV_REORDER)) != NULL)
+	if ((cp = __libc_secure_getenv(ENV_REORDER)) != NULL)
 		if (checkbuf(cp, CMD_ON))
 			reorder = 1;
 		else
 			reorder = 0;
 
 	/* add trimdomains from environment variable */
-	if(NULL!=(cp=getenv(ENV_TRIM_ADD))){
+	if(NULL!=(cp=__libc_secure_getenv(ENV_TRIM_ADD))){
 		if(NULL!=(cp=strtok(cp, TOKEN_SEPARATORS))){
 			do{
 				if(numtrimdomains<MAXTRIMDOMAINS){
@@ -564,7 +577,7 @@
 	}
 
 	/* override trimdomains from environment variable */
-	if(NULL!=(cp=getenv(ENV_TRIM_OVERR))){
+	if(NULL!=(cp=__libc_secure_getenv(ENV_TRIM_OVERR))){
 		numtrimdomains=0;
 		tdp=trimdomainbuf;
 		if(NULL!=(cp=strtok(cp, TOKEN_SEPARATORS))){
@@ -789,6 +802,12 @@
 				register int nn;
 
 				host.h_length = n;
+				if(host.h_length>4)
+				{
+					syslog(LOG_NOTICE|LOG_AUTH,
+						"Attempt to feed me an overlong A record. Probably a breakin attempt.");
+					host.h_length=4;
+				}
 				host.h_addrtype = (class == C_IN)
 						  ? AF_INET
 						  : AF_UNSPEC;
@@ -1307,7 +1326,8 @@
 
 	aliases[0]=NULL;
 	aliases[1]=NULL;
-	(void) strcpy(namebuf, name);
+	(void) strncpy(namebuf, name,sizeof(namebuf));
+	namebuf[sizeof(namebuf)-1]=0;
 
 	(void)gethostname(localname, sizeof(localname));
 
@@ -1320,7 +1340,8 @@
 				if (strcasecmp(*cp, name) == 0){
 					found++;
 					aliases[0]=name;
-					(void) strcpy(namebuf, p->h_name);
+					(void) strncpy(namebuf, p->h_name,
+						sizeof(namebuf));
 				}
 		if (strcasecmp(p->h_name, localname) == 0)
 			localfound++;
--- libc-sparc-5.3.12.orig/libc/inet/rcmd.c
+++ libc-sparc-5.3.12/libc/inet/rcmd.c
@@ -122,7 +122,12 @@
 		fcntl(s, F_SETOWN, pid);
 #endif
 		sin.sin_family = hp->h_addrtype;
-		bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
+		/*
+		 *	XXX need to make this do AF_INET6 one day, but not
+		 *	now. Hard code to 4 to help shield from buggy
+		 *	resolvers, tho I've fixed the NYS resolver I hope
+		 */
+		bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, 4);
 		sin.sin_port = rport;
 		if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
 			break;
--- libc-sparc-5.3.12.orig/libc/inet/res_debug.c
+++ libc-sparc-5.3.12/libc/inet/res_debug.c
@@ -766,7 +766,7 @@
 __p_time(value)
 	u_int32_t value;
 {
-	static char nbuf[40];
+	static char nbuf[120];
 	int secs, mins, hours, days;
 	register char *p;
 
--- libc-sparc-5.3.12.orig/libc/inet/res_init.c
+++ libc-sparc-5.3.12/libc/inet/res_init.c
@@ -72,6 +72,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+extern char *__libc_secure_getenv(const char *);
+
 /*-------------------------------------- info about "sortlist" --------------
  * Marc Majka		1994/04/16
  * Allan Nathanson	1994/10/29 (BIND 4.9.3.x)
@@ -200,7 +202,7 @@
 	_res.pfcode = 0;
 
 	/* Allow user to override the local domain definition */
-	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
+	if ((cp = __libc_secure_getenv("LOCALDOMAIN")) != NULL) {
 		(void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
 		haveenv++;
 
@@ -405,7 +407,7 @@
 #endif /* !RFC1535 */
 	}
 
-	if ((cp = getenv("RES_OPTIONS")) != NULL)
+	if ((cp = __libc_secure_getenv("RES_OPTIONS")) != NULL)
 		res_setoptions(cp, "env");
 	_res.options |= RES_INIT;
 	return (0);
--- libc-sparc-5.3.12.orig/libc/inet/res_query.c
+++ libc-sparc-5.3.12/libc/inet/res_query.c
@@ -71,6 +71,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+extern char *__libc_secure_getenv(const char *);
+
 #include "res_options.h"
 
 #if PACKETSZ > 1024
@@ -360,7 +362,7 @@
 
 	if (_res.options & RES_NOALIASES)
 		return (NULL);
-	file = getenv("HOSTALIASES");
+	file = __libc_secure_getenv("HOSTALIASES");
 	if (file == NULL || (fp = fopen(file, "r")) == NULL)
 		return (NULL);
 	setbuf(fp, NULL);
--- libc-sparc-5.3.12.orig/libc/inet/rexec.c
+++ libc-sparc-5.3.12/libc/inet/rexec.c
@@ -102,7 +102,7 @@
 		(void) write(s, "", 1);
 		port = 0;
 	} else {
-		char num[8];
+		char num[32];
 		int s2, sin2len;
 		
 		s2 = socket(AF_INET, SOCK_STREAM, 0);
--- libc-sparc-5.3.12.orig/libc/inet/ruserpass.c
+++ libc-sparc-5.3.12/libc/inet/ruserpass.c
@@ -22,6 +22,7 @@
 #include "inetprivate.h"
 #include <sys/stat.h>
 #include <utmp.h>
+#include "utmp-wrap.h"
 #include <pwd.h>
 #include <errno.h>
 #include <netdb.h>
@@ -180,7 +181,7 @@
 static void
 rnetrc(const char *host, char **aname, char **apass)
 {
-	char *hdir, buf[BUFSIZ];
+	char *hdir, *buf;
 	int t;
 	struct stat stb;
 	struct hostent *hp;
@@ -188,9 +189,10 @@
 #if NLS
 	libc_nls_init();
 #endif
-	hdir = getenv("HOME");
+	hdir = __libc_secure_getenv("HOME");
 	if (hdir == NULL)
-		hdir = ".";
+		return;
+  	buf = alloca (strlen (hdir) + sizeof ("/.netrc") + 1);
 	(void)sprintf(buf, "%s/.netrc", hdir);
 	cfile = fopen(buf, "r");
 	if (cfile == NULL) {
@@ -823,7 +825,9 @@
 static
 struct utmp *getutmp(char *sttyname)
 {
-	static struct utmp utmpstr;
+	static struct new_utmp utmpstr;
+	static struct utmp utmp_res;
+
 	FILE *fdutmp;
 
 	if(sttyname == NULL || sttyname[0] == 0)return(NULL);
@@ -834,7 +838,8 @@
 	while(fread(&utmpstr,1,sizeof utmpstr,fdutmp) == sizeof utmpstr)
 		if(strcmp(utmpstr.ut_line,sttyname+5) == 0){
 			fclose(fdutmp);
-			return(&utmpstr);
+			__newutmp_to_old( &utmpstr , &utmp_res);
+			return(&utmp_res);
 		}
 	fclose(fdutmp);
 	return(NULL);
--- libc-sparc-5.3.12.orig/libc/libio/iotempname.c
+++ libc-sparc-5.3.12/libc/libio/iotempname.c
@@ -30,6 +30,8 @@
 #include "libioP.h"
 #include "stdio.h"
 
+extern char *__libc_secure_getenv(const char *);
+
 #ifndef _IO_open
 #define _IO_open open
 #endif
@@ -137,7 +139,7 @@
 
   if (dir_search)
     {
-      register CONST char *d = getenv("TMPDIR");
+      register CONST char *d = __libc_secure_getenv("TMPDIR");
       if (d != NULL && !diraccess(d))
 	d = NULL;
       if (d == NULL && dir != NULL && diraccess(dir))
--- libc-sparc-5.3.12.orig/libc/libio/printf_fp.c
+++ libc-sparc-5.3.12/libc/libio/printf_fp.c
@@ -41,6 +41,20 @@
 #include <unistd.h>
 #include <stdlib.h>
 
+#ifdef __WANT_CLZ_TAB
+const UQItype __clz_tab[] =
+{
+  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+#endif
+
 #define NDEBUG			/* Undefine this for debugging assertions.  */
 #include <assert.h>
 
--- libc-sparc-5.3.12.orig/libc/locale/setlocale.c
+++ libc-sparc-5.3.12/libc/locale/setlocale.c
@@ -261,7 +261,7 @@
       if (*name == '\0')
       {
 	/* First try LC_ALL. */
-	name = getenv ("LC_ALL");
+	name = __libc_secure_getenv ("LC_ALL");
       }      
 
       if (!name || name[0] == '\0')
@@ -272,7 +272,7 @@
 	{
 	  name = getenv (_nl_category_names[category]);
 	  if (!name || name[0] == '\0')
-	     name = getenv ("LANG");
+	     name = __libc_secure_getenv ("LANG");
 	  if (!name || name[0] == '\0')
 	    name = _nl_current_names[category];
 
@@ -438,9 +438,9 @@
       if (name[0] == '\0')
       {
 	/* Get the native environment. */
-	name = getenv (_nl_category_names[category]);
+	name = __libc_secure_getenv (_nl_category_names[category]);
 	if (!name || name[0] == '\0')
-	  name = getenv ("LANG");
+	  name = __libc_secure_getenv ("LANG");
 	if (!name || name[0] == '\0')
 	  name = _nl_current_names[category];
       }
--- libc-sparc-5.3.12.orig/libc/login/Makefile
+++ libc-sparc-5.3.12/libc/login/Makefile
@@ -11,7 +11,7 @@
 
 DIRS:=
 
-SRCS = getlogin.c getpass.c utmp2.c
+SRCS = getlogin.c getpass.c utmp_file.c utmp-wrap.c utmp2.c
 ASMS= $(SRCS:.c=.s)
 OBJS= $(SRCS:.c=.o)
 ALIASES=
--- libc-sparc-5.3.12.orig/libc/login/getlogin.c
+++ libc-sparc-5.3.12/libc/login/getlogin.c
@@ -3,6 +3,7 @@
 #include <sys/types.h>
 #include <fcntl.h>
 #include <utmp.h>
+#include "utmp-wrap.h"
 #include <unistd.h>
 #include <memory.h>
 #include <pwd.h>
@@ -18,7 +19,7 @@
 char *getlogin(void)
 {
 	char *ttyn;
-	struct utmp ut;
+	struct new_utmp ut;
 	int fd;
 	
 	if(!(ttyn = ttyname(0)) && !(ttyn = ttyname(1))
--- libc-sparc-5.3.12.orig/libc/login/utmp2.c
+++ libc-sparc-5.3.12/libc/login/utmp2.c
@@ -5,14 +5,15 @@
    conform to the XPG2 and SVID2 standards */
    
 #include "utmp.h"
+#include "utmp-wrap.h"
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
 #include <stdio.h>
 
-static char Utname[] = _PATH_UTMP;
+static char Utname[1024] = _PATH_UTMP;
 static int Fd = -1;
-static struct utmp Ut;
+static struct old_utmp Ut;
 
 /* kludge for the benefit of getutent() whose semantics differs from the
    other get..() functions. When set, getutent() will not read the 
@@ -20,7 +21,17 @@
    flag. */
 static int _getutent_flag = 0;
 
-static int _setutent(void)
+static int _old_setutent(void);
+void old_setutent(void);
+void old_utmpname(const char *name);
+struct old_utmp *old_getutent(void);
+struct old_utmp *old_getutid(struct old_utmp *ut);
+struct old_utmp *old_getutline(struct old_utmp *ut);
+static struct old_utmp *_pututline(struct old_utmp *ut);
+void old_pututline(struct old_utmp *ut);
+void old_endutent(void);
+
+static int _old_setutent(void)
 {
 	if(Fd != -1) close(Fd);
 	
@@ -33,19 +44,20 @@
 			return 0;
 		}
 	}
-	if(read(Fd, (char *)&Ut, sizeof(Ut)) != sizeof(Ut))
+	if(read(Fd, (char *)&Ut, sizeof(Ut)) != sizeof(Ut)) {
+		Ut.ut_id[0]='\0';
 		return 0;
-
+	}
 	return 1;
 }
 
-void setutent(void)
+void old_setutent(void)
 {
-	(void)_setutent();
+	(void)_old_setutent();
 	_getutent_flag = 1;
 }
 
-void utmpname(const char *name)
+void old_utmpname(const char *name)
 {
 	(void)strncpy(Utname, name, sizeof(Utname)-1);
 	if(Fd != -1) close(Fd);
@@ -53,11 +65,11 @@
 }
 
 /* always get the logical *next* entry from the utmp file */
-struct utmp *getutent(void)
+struct old_utmp *old_getutent(void)
 {
 	if(Fd == -1) {
-		if(!_setutent())
-			return (struct utmp *)0;
+		if(!_old_setutent())
+			return (struct old_utmp *)0;
 		else {
 			_getutent_flag = 0;
 			return &Ut;
@@ -71,15 +83,15 @@
 	}
 
 	if(read(Fd, (char *)&Ut, sizeof(Ut)) != sizeof(Ut))
-		return (struct utmp *)0;
+		return (struct old_utmp *)0;
 	else
 		return &Ut;
 }
 
-struct utmp *getutid(struct utmp *ut)
+struct old_utmp *old_getutid(struct old_utmp *ut)
 {
 	if(Fd == -1)
-		if(!_setutent()) return (struct utmp *)0;
+		if(!_old_setutent()) return (struct old_utmp *)0;
 	
 	do {
 		if(RUN_LVL <= ut->ut_type && ut->ut_type <= OLD_TIME &&
@@ -91,13 +103,13 @@
 		
 	} while(read(Fd, (char *)&Ut, sizeof(Ut)) == sizeof(Ut));
 
-	return (struct utmp *)0;
+	return (struct old_utmp *)0;
 }
 
-struct utmp *getutline(struct utmp *ut)
+struct old_utmp *old_getutline(struct old_utmp *ut)
 {
 	if(Fd == -1)
-		if(!_setutent()) return (struct utmp *)0;
+		if(!_old_setutent()) return (struct old_utmp *)0;
 	
 	do {
 		if((Ut.ut_type == USER_PROCESS || Ut.ut_type == LOGIN_PROCESS)
@@ -105,12 +117,12 @@
 		return &Ut;
 	} while(read(Fd, (char *)&Ut, sizeof(Ut)) == sizeof(Ut));
 
-	return (struct utmp *)0;
+	return (struct old_utmp *)0;
 }
 
-struct utmp *_pututline(struct utmp *ut)
+struct old_utmp *_pututline(struct old_utmp *ut)
 {
-	struct utmp my_ut;
+	struct old_utmp my_ut;
 	
 	/* don't stomp on the new value even if it's in Ut */
 	if(ut == &Ut) {
@@ -121,14 +133,14 @@
 	/* we don't check Fd here, getutid() does it for us; this way
 	   we can create an utmp file from an empty file, if it should
 	   get lost. */
-	if(getutid(ut)) {
+	if(old_getutid(ut)) {
 		(void)lseek(Fd, (off_t)-sizeof(Ut), SEEK_CUR);
 		if(write(Fd, (char *)ut, sizeof(Ut)) != sizeof(Ut))
-			return (struct utmp *)0;
+			return (struct old_utmp *)0;
 	} else {
 		(void)lseek(Fd, (off_t)0, SEEK_END);
 		if(write(Fd, (char *)ut, sizeof(Ut)) != sizeof(Ut))
-			return (struct utmp *)0;
+			return (struct old_utmp *)0;
 	}
 	
 	/* if we get this far, we are successful */
@@ -138,12 +150,13 @@
 	return &Ut;
 }
 
-void pututline(struct utmp *ut)
+void old_pututline(struct old_utmp *ut)
 {
-	(void)_pututline(ut);
+	/* (void)_pututline(ut); */
+	if (_pututline(ut)==NULL) fprintf(stderr,"FEHLER\n");
 }
 
-void endutent(void)
+void old_endutent(void)
 {
 	if(Fd != -1) close(Fd);
 	Fd = -1;
--- libc-sparc-5.3.12.orig/libc/login/utmp-wrap.c
+++ libc-sparc-5.3.12/libc/login/utmp-wrap.c
@@ -0,0 +1,155 @@
+/*********************************************************************
+
+        UTMP wrapper routines :
+
+     Copyright (C) 1997 by Helmut Geyer
+
+   This program is free software;you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+**********************************************************************/
+
+#include "utmp-wrap.h" 
+#include <string.h>
+
+void __oldutmp_to_new __P ((struct old_utmp *, struct new_utmp *));
+void __newutmp_to_old __P ((struct new_utmp *, struct old_utmp *));
+
+void    setutent __P ((void));
+void    utmpname __P ((__const char *));
+struct utmp   *getutent __P ((void));
+struct utmp   *getutid __P ((struct utmp *));
+struct utmp   *getutline __P ((struct utmp *));
+void    pututline __P ((struct utmp *));
+void    endutent __P ((void));
+
+static struct new_utmp N_ut;
+static struct old_utmp O_ut;
+
+#define N_TO_O(A)  o_ut->A = n_ut->A 
+#define O_TO_N(A)  n_ut->A = o_ut->A 
+
+
+void __oldutmp_to_new ( struct old_utmp *o_ut, struct new_utmp *n_ut)
+{
+  int i;
+  
+  /* simple translation for matching fields */
+  O_TO_N(ut_type);
+  O_TO_N(ut_pid);
+  for (i=0; i<4; i++) O_TO_N(ut_id[i]);
+  /* copy strings. the new ones always have more space than the old ones.
+     Add a null, even if it isn't needed.*/
+  strncpy( n_ut->ut_line, o_ut->ut_line, O_UT_LINESIZE);
+  n_ut->ut_line[O_UT_LINESIZE]='\0';
+  strncpy( n_ut->ut_user, o_ut->ut_user, O_UT_NAMESIZE);
+  n_ut->ut_user[O_UT_NAMESIZE]='\0';
+  strncpy( n_ut->ut_host, o_ut->ut_host, O_UT_HOSTSIZE);
+  n_ut->ut_host[O_UT_HOSTSIZE]='\0';
+
+  n_ut->ut_tv.tv_sec=o_ut->ut_time;
+  n_ut->ut_tv.tv_usec=0;
+  
+  /* I hope this is doing the right thing for ipv6 */
+  n_ut->ut_addr_v6[0]=o_ut->ut_addr;
+  n_ut->ut_addr_v6[1]=0xffff;  /* this is for ipv4 hosts that 
+                                cannot understand ipv6*/
+  n_ut->ut_addr_v6[2]=0;
+  n_ut->ut_addr_v6[3]=0;
+  
+  /* these are additional in the new one. Try settting all to 0 */
+  n_ut->ut_exit.e_termination=0;
+  n_ut->ut_exit.e_exit=0;
+  n_ut->ut_session=0;
+}
+
+void __newutmp_to_old ( struct new_utmp *n_ut, struct old_utmp *o_ut)
+{
+    int i;
+  
+  /* simple translation for matching fields */
+  N_TO_O(ut_type);
+  N_TO_O(ut_pid);
+  for (i=0; i<4; i++) N_TO_O(ut_id[i]);
+  /* copy strings. the new ones always have more space than the old ones.
+     Make sure the  strings are null-terminated when needed */
+  strncpy( o_ut->ut_line, n_ut->ut_line, O_UT_LINESIZE);
+  o_ut->ut_line[O_UT_LINESIZE-1]='\0';
+  strncpy( o_ut->ut_user, n_ut->ut_user, O_UT_NAMESIZE);
+  /* not really sure, whether this is meant to be null-terminated. 
+     let's be careful about it. */  
+  strncpy( o_ut->ut_host, n_ut->ut_host, O_UT_HOSTSIZE);
+  o_ut->ut_host[O_UT_HOSTSIZE-1]='\0';
+
+  o_ut->ut_time=n_ut->ut_tv.tv_sec;
+ 
+  o_ut->ut_addr=n_ut->ut_addr_v6[0];
+}
+
+void setutent (void)
+{
+  (void)setutent_file(1);
+}
+
+void utmpname (const char *name)
+{
+  (void)utmpname_file(name);
+}
+
+void endutent (void)
+{
+  (void)endutent_file();
+}
+
+struct utmp *getutent (void)
+{
+  struct new_utmp *result;
+
+  if (getutent_r_file (&N_ut, &result) < 0)
+    return NULL;
+  
+  __newutmp_to_old (result,&O_ut);
+  
+  return (struct utmp *)&O_ut;
+}
+
+struct utmp *getutid (struct utmp *id)
+{
+  struct new_utmp *result;
+  struct new_utmp n_id;
+  
+  __oldutmp_to_new ((struct old_utmp *)id, &n_id);
+
+  if (getutid_r_file ((const struct new_utmp *)&n_id, &N_ut, &result) < 0)
+    return NULL;
+  
+  __newutmp_to_old (result,&O_ut);
+  
+  return (struct utmp *)&O_ut;
+}
+
+struct utmp *getutline ( struct utmp *line)
+{
+  struct new_utmp *result;
+  struct new_utmp n_line;
+  
+  __oldutmp_to_new ((struct old_utmp *)line,&n_line);
+
+  if (getutline_r_file ((const struct new_utmp *)&n_line, &N_ut, &result) < 0)
+    return NULL;
+  
+  __newutmp_to_old (result,&O_ut);
+  
+  return (struct utmp *)&O_ut;
+}
+
+void pututline (struct utmp *data)
+{
+  struct new_utmp n_data;
+  
+  __oldutmp_to_new ((struct old_utmp *)data, &n_data);
+  
+  (void) pututline_file((const struct new_utmp *)&n_data);
+}
--- libc-sparc-5.3.12.orig/libc/login/utmp_file.c
+++ libc-sparc-5.3.12/libc/login/utmp_file.c
@@ -0,0 +1,416 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>
+   and Paul Janzen <pcj@primenet.com>, 1996.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "utmp-wrap.h"
+#include <sys/file.h>
+#include <sys/stat.h>
+
+
+/* This is the default name.  */
+static const char default_file_name[] = _PATH_UTMP;
+
+/* Current file name.  */
+static const char *file_name = (const char *) default_file_name;
+
+/* Descriptor for the file and position.  */
+static int file_fd = INT_MIN;
+static off_t file_offset;
+
+static struct new_utmp last_entry;
+
+/* Functions defined here.  */
+ int setutent_file (int reset);
+ int getutent_r_file (struct new_utmp *buffer, struct new_utmp **result);
+ int getutid_r_file (const struct new_utmp *key, struct new_utmp *buffer,
+			   struct new_utmp **result);
+ int getutline_r_file (const struct new_utmp *key, struct new_utmp *buffer,
+			     struct new_utmp **result);
+ struct new_utmp *pututline_file (const struct new_utmp *data);
+ void endutent_file (void);
+ int utmpname_file (const char *name);
+
+ int
+setutent_file (int reset)
+{
+  if (file_fd == INT_MIN)
+    {
+      file_fd = open (file_name, O_RDWR);
+      if (file_fd == -1)
+	{
+	  /* Hhm, read-write access did not work.  Try read-only.  */
+	  file_fd = open (file_name, O_RDONLY);
+	  if (file_fd == -1)
+	    {
+	      perror ("while opening UTMP file");
+	      return 0;
+	    }
+	}
+      file_offset = 0;
+
+#if _HAVE_UT_TYPE - 0
+      /* Make sure the entry won't match.  */
+      last_entry.ut_type = -1;
+#endif
+    }
+  else if (reset)
+    {
+      lseek (file_fd, 0, SEEK_SET);
+
+      /* Remember we are at beginning of file.  */
+      file_offset = 0;
+
+#if _HAVE_UT_TYPE - 0
+      /* Make sure the entry won't match.  */
+      last_entry.ut_type = -1;
+#endif
+    }
+
+  return 1;
+}
+
+
+ void
+endutent_file (void)
+{
+  if (file_fd >= 0)
+    close (file_fd);
+
+  file_fd = INT_MIN;
+}
+
+
+ int
+getutent_r_file (struct new_utmp *buffer, struct new_utmp **result)
+{
+  int nbytes;
+  struct flock fl;			/* Information struct for locking.  */
+
+  /* Open utmp file if not already done.  */
+  if (file_fd == INT_MIN)
+    setutent_file (1);
+
+  if (file_fd == -1 || file_offset == -1l)
+    {
+      /* Not available.  */
+      *result = NULL;
+      return -1;
+    }
+
+  /* XXX The following is not perfect.  Instead of locking the file itself
+     Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl> suggests to
+     use an extra locking file.  */
+
+  /* Try to get the lock.  */
+  memset (&fl, '\0', sizeof (struct flock));
+  fl.l_type = F_WRLCK;
+  fl.l_whence = SEEK_SET;
+  fcntl (file_fd, F_SETLKW, &fl);
+
+  /* Read the next entry.  */
+  nbytes = read (file_fd, &last_entry, sizeof (struct new_utmp));
+
+  /* And unlock the file.  */
+  fl.l_type = F_UNLCK;
+  fcntl (file_fd, F_SETLKW, &fl);
+
+  if (nbytes != sizeof (struct new_utmp))
+    {
+      file_offset = -1l;
+      *result = NULL;
+      return -1;
+    }
+
+  /* Update position pointer.  */
+  file_offset += sizeof (struct new_utmp);
+
+  memcpy (buffer, &last_entry, sizeof (struct new_utmp));
+  *result = buffer;
+
+  return 0;
+}
+
+
+/* For implementing this function we don't use the getutent_r function
+   because we can avoid the reposition on every new entry this way.  */
+ int
+getutline_r_file (const struct new_utmp *line, struct new_utmp *buffer,
+		  struct new_utmp **result)
+{
+  if (file_fd < 0 || file_offset == -1l)
+    {
+      *result = NULL;
+      return -1;
+    }
+
+  while (1)
+    {
+      /* Read the next entry.  */
+      if (read (file_fd, &last_entry, sizeof (struct new_utmp))
+	  != sizeof (struct new_utmp))
+	{
+	  errno= ESRCH;
+	  file_offset = -1l;
+	  *result = NULL;
+	  return -1;
+	}
+      file_offset += sizeof (struct new_utmp);
+
+      /* Stop if we found a user or login entry.  */
+      if (
+#if _HAVE_UT_TYPE - 0
+	  (last_entry.ut_type == USER_PROCESS
+	   || last_entry.ut_type == LOGIN_PROCESS)
+	  &&
+#endif
+	  !strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line))
+	break;
+    }
+
+  memcpy (buffer, &last_entry, sizeof (struct new_utmp));
+  *result = buffer;
+
+  return 0;
+}
+
+
+ int
+proc_utmp_eq (const struct new_utmp *entry, const struct new_utmp *match)
+{
+  return
+    (
+#if _HAVE_UT_TYPE - 0
+     (entry->ut_type == INIT_PROCESS
+      || entry->ut_type == LOGIN_PROCESS
+      || entry->ut_type == USER_PROCESS
+      || entry->ut_type == DEAD_PROCESS)
+     &&
+     (match->ut_type == INIT_PROCESS
+      || match->ut_type == LOGIN_PROCESS
+      || match->ut_type == USER_PROCESS
+      || match->ut_type == DEAD_PROCESS)
+     &&
+#endif
+#if _HAVE_UT_ID - 0
+     (entry->ut_id[0] && match->ut_id[0]
+      ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0
+      : strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0)
+#else
+     strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0
+#endif
+     );
+}
+
+ int
+internal_getut_r (const struct new_utmp *id, struct new_utmp *buffer)
+{
+#if _HAVE_UT_TYPE - 0
+  if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME
+      || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME)
+    {
+      /* Search for next entry with type RUN_LVL, BOOT_TIME,
+	 OLD_TIME, or NEW_TIME.  */
+
+      while (1)
+	{
+	  /* Read the next entry.  */
+	  if (read (file_fd, buffer, sizeof (struct new_utmp))
+	      != sizeof (struct new_utmp))
+	    {
+	      errno=ESRCH;
+	      file_offset = -1l;
+	      return -1;
+	    }
+	  file_offset += sizeof (struct new_utmp);
+
+	  if (id->ut_type == buffer->ut_type)
+	    break;
+	}
+    }
+  else
+#endif /* _HAVE_UT_TYPE */
+    {
+      /* Search for the next entry with the specified ID and with type
+	 INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS.  */
+
+      while (1)
+	{
+	  /* Read the next entry.  */
+	  if (read (file_fd, buffer, sizeof (struct new_utmp))
+	      != sizeof (struct new_utmp))
+	    {
+	      errno=ESRCH;
+	      file_offset = -1l;
+	      return -1;
+	    }
+	  file_offset += sizeof (struct new_utmp);
+
+	  if (proc_utmp_eq (buffer, id))
+	    break;
+	}
+    }
+
+  return 0;
+}
+
+
+/* For implementing this function we don't use the getutent_r function
+   because we can avoid the reposition on every new entry this way.  */
+ int
+getutid_r_file (const struct new_utmp *id, struct new_utmp *buffer,
+		struct new_utmp **result)
+{
+  if (file_fd < 0 || file_offset == -1l)
+    {
+      *result = NULL;
+      return -1;
+    }
+
+  if (internal_getut_r (id, &last_entry) < 0)
+    {
+      *result = NULL;
+      return -1;
+    }
+
+  memcpy (buffer, &last_entry, sizeof (struct new_utmp));
+  *result = buffer;
+
+  return 0;
+}
+
+
+ struct new_utmp *
+pututline_file (const struct new_utmp *data)
+{
+  struct flock fl;			/* Information struct for locking.  */
+  struct new_utmp buffer;
+  struct new_utmp *pbuf;
+  int found;
+
+  if (file_fd < 0)
+    /* Something went wrong.  */
+    return NULL;
+
+  if (file_fd == INT_MIN)
+    /* The file is closed.  Open it again.  */
+    setutent_file (0);
+
+  /* Find the correct place to insert the data.  */
+  if (file_offset > 0
+      && (
+#if _HAVE_UT_TYPE - 0
+	  (last_entry.ut_type == data->ut_type
+	   && (last_entry.ut_type == RUN_LVL
+	       || last_entry.ut_type == BOOT_TIME
+	       || last_entry.ut_type == OLD_TIME
+	       || last_entry.ut_type == NEW_TIME))
+	  ||
+#endif
+	  proc_utmp_eq (&last_entry, data)))
+    found = 1;
+  else
+    found = internal_getut_r (data, &buffer);
+
+  /* Try to lock the file.  */
+  memset (&fl, '\0', sizeof (struct flock));
+  fl.l_type = F_WRLCK;
+  fl.l_whence = SEEK_SET;
+  fcntl (file_fd, F_SETLKW, &fl);
+
+  if (found < 0)
+    {
+      /* We append the next entry.  */
+      file_offset = lseek (file_fd, 0, SEEK_END);
+      if (file_offset % sizeof (struct new_utmp) != 0)
+	{
+	  file_offset -= file_offset % sizeof (struct new_utmp);
+	  ftruncate (file_fd, file_offset);
+
+	  if (lseek (file_fd, 0, SEEK_END) < 0)
+	    {
+	      pbuf = NULL;
+	      goto unlock_return;
+	    }
+	}
+    }
+  else
+    {
+      /* We replace the just read entry.  */
+      file_offset -= sizeof (struct new_utmp);
+      lseek (file_fd, file_offset, SEEK_SET);
+    }
+
+  /* Write the new data.  */
+  if (write (file_fd, data, sizeof (struct new_utmp)) != sizeof (struct new_utmp)
+      /* If we appended a new record this is only partially written.
+	 Remove it.  */
+      && found < 0)
+    {
+      (void) ftruncate (file_fd, file_offset);
+      pbuf = NULL;
+    }
+  else
+    {
+      file_offset += sizeof (struct new_utmp);
+      pbuf = (struct new_utmp *) data;
+    }
+
+ unlock_return:
+   /* And unlock the file.  */
+  fl.l_type = F_UNLCK;
+  fcntl (file_fd, F_SETLKW, &fl);
+
+  return pbuf;
+}
+
+
+ int
+utmpname_file (const char *name)
+{
+  if (strcmp (name, file_name) != 0)
+    {
+      if (strcmp (name, default_file_name) == 0)
+	{
+	  if (file_name != default_file_name)
+	    free ((char *) file_name);
+
+	  file_name = default_file_name;
+	}
+      else
+	{
+	  char *new_name = strdup (name);
+	  if (new_name == NULL)
+	    /* Out of memory.  */
+	    return -1;
+
+	  if (file_name != default_file_name)
+	    free ((char *) file_name);
+
+	  file_name = new_name;
+	}
+    }
+  return 0;
+}
--- libc-sparc-5.3.12.orig/libc/malloc/mtrace.c
+++ libc-sparc-5.3.12/libc/malloc/mtrace.c
@@ -130,7 +130,7 @@
 {
   char *mallfile;
 
-  mallfile = getenv (mallenv);
+  mallfile = __libc_secure_getenv (mallenv);
   if (mallfile != NULL || mallwatch != NULL)
     {
       mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w");
--- libc-sparc-5.3.12.orig/libc/nls/msgcat.c
+++ libc-sparc-5.3.12/libc/nls/msgcat.c
@@ -115,7 +115,7 @@
 #include <sys/mman.h>
 #endif
 
-nl_catd 	catopen( name, type)
+nl_catd catopen( name, type)
 const char *name;
 int type;
 {
@@ -126,6 +126,7 @@
     long	len;
     char	*base, *cptr, *pathP;
     struct stat	sbuf;
+    int left=MAXPATHLEN-1;
     
     if (!name || !*name) return(NLERR);
     if (*name == '/') {
@@ -139,7 +140,8 @@
 	if ((lang = (char *) setlocale(LC_MESSAGES,(char *) NULL)) == NULL)
 		lang="C";
 #endif
-	if ((nlspath = (char *) getenv("NLSPATH")) == NULL) {
+	if ((nlspath = (char *) getenv("NLSPATH")) == NULL) 
+	{
 #if OLD_NLS_PATHS
 	    nlspath = "/nlslib/%L/%N.cat:/nlslib/%N/%L";
 #else
@@ -159,26 +161,49 @@
 	
 	len = strlen(nlspath);
 	base = cptr = (char *) malloc(len + 2);
-	if (!base) return(NLERR);
+	if (!base)
+		return(NLERR);
 	strcpy(cptr, nlspath);
 	cptr[len] = ':';
 	cptr[len+1] = '\0';
         
-	for (nlspath = cptr; *cptr; ++cptr) {
-	    if (*cptr == ':') {
+	for (nlspath = cptr; *cptr; ++cptr) 
+	{
+	    if (*cptr == ':') 
+	    {
 		*cptr = '\0';
-		for (pathP = path; *nlspath; ++nlspath) {
-		    if (*nlspath == '%') {
-			if (*(nlspath + 1) == 'L') {
+		for (pathP = path; *nlspath && left>0; ++nlspath) 
+		{
+		    if (*nlspath == '%') 
+		    {
+			if (*(nlspath + 1) == 'L') 
+			{
 			    ++nlspath;
-			    strcpy(pathP, lang);
+			    strncpy(pathP, lang, left);
 			    pathP += strlen(lang);
-			} else if (*(nlspath + 1) == 'N') {
+			    left-=strlen(lang);
+			}
+			else if (*(nlspath + 1) == 'N') 
+			{
 			    ++nlspath;
-			    strcpy(pathP, name);
+			    strncpy(pathP, name, left);
 			    pathP += strlen(name);
-			} else *(pathP++) = *nlspath;
-		    } else *(pathP++) = *nlspath;
+			    left-=strlen(name);
+			} 
+			else 
+			{
+				if(left)
+				{
+					*(pathP++) = *nlspath;
+					left--;
+				}
+			}
+		    } 
+		    else
+		    {
+		    		*(pathP++) = *nlspath;
+		    		left--;
+		    }
 		}
 		*pathP = '\0';
 		if (stat(path, &sbuf) == 0) {
@@ -189,9 +214,12 @@
 	    }
 	}
 	free(base);
-	if (tmppath) free(tmppath);
+	
+	if (tmppath) 
+		free(tmppath);
 
-	if (!catpath) return(NLERR);
+	if (!catpath) 
+		return(NLERR);
     }
 
 #ifdef HAVE_MMAP
@@ -231,22 +259,29 @@
     if (cat==(MCCatT *)NLERR || !cat || setId <= 0) return(NULL);
 
     lo = 0;
-    if (setId - 1 < cat->numSets) {
+    if (setId - 1 < cat->numSets) 
+    {
 	cur = setId - 1;
 	hi = setId;
-    } else {
+    }
+    else 
+    {
 	hi = cat->numSets;
 	cur = (hi - lo) / 2;
     }
     
-    while (True) {
+    while (True) 
+    {
 	set = cat->sets + cur;
 	if (set->setId == setId) break;
-	if (set->setId < setId) {
+	if (set->setId < setId) 
+	{
 	    lo = cur+1;
 	    if (hi > cur + (setId - set->setId) + 1) hi = cur+(setId-set->setId)+1;
 	    dir = 1;
-	} else {
+	}
+	else
+	{
 	    hi = cur;
 	    dir = -1;
 	}
--- libc-sparc-5.3.12.orig/libc/nys/Makefile
+++ libc-sparc-5.3.12/libc/nys/Makefile
@@ -23,6 +23,9 @@
 #
 # Author: Peter Eriksson <pen@signum.se>, 5 Augh 1993
 #
+TOPDIR=..
+include $(TOPDIR)/Makeconfig
+include $(TOPDIR)/Makerules
 
 ifneq ($(NYS),true)
 
--- libc-sparc-5.3.12.orig/libc/nys/nsw/src/nsswitch.c
+++ libc-sparc-5.3.12/libc/nys/nsw/src/nsswitch.c
@@ -43,8 +43,8 @@
 	fclose(nswfp);
 
 #ifdef DEBUG
-    if (getenv("NSWCONF"))
-	nswfp = fopen(getenv("NSWCONF"), "r");
+    if (__libc_secure_getenv("NSWCONF"))
+	nswfp = fopen(__libc_secure_getenv("NSWCONF"), "r");
     else
 #endif
 
--- libc-sparc-5.3.12.orig/libc/nys/nsw/src/yp/yp_misc.c
+++ libc-sparc-5.3.12/libc/nys/nsw/src/yp/yp_misc.c
@@ -92,10 +92,12 @@
      * simplify parsing of the YP maps.  MAG.
      */
 
-    if (delim == ' ')
+    if (delim == ' '){
        while (*str && (!isspace(*str)))
 	  str++;
-    else
+       while (*str && *(str+1) && isspace (*(str+1)))
+	  str++;
+    } else
        while (*str && *str != delim)
 	  str++;
 
--- libc-sparc-5.3.12.orig/libc/nys/yp/src/yp_if.c
+++ libc-sparc-5.3.12/libc/nys/yp/src/yp_if.c
@@ -251,7 +251,7 @@
     if (code!= 0)
 	return code;
 
-    cp = getenv("YPDOMAIN");
+    cp = __libc_secure_getenv("YPDOMAIN");
     if (cp)
     {
 	*outdomain = strdup(cp);
--- libc-sparc-5.3.12.orig/libc/posix/Makefile
+++ libc-sparc-5.3.12/libc/posix/Makefile
@@ -18,7 +18,7 @@
 
 SRC1S= cfmakeraw.c cfsetget.c clock.c confstr.c ctermid.c cuserid.c \
 	execl.c execle.c execlp.c execv.c execvp.c \
-	fnmatch.c getenv.c \
+	fnmatch.c getenv.c getenvsec.c \
 	getopt.c getopt1.c killpg.c mktemp.c \
 	putenv.c raise.c sleep.c system.c tcdrain.c \
 	tcflow.c tcflush.c tcgetpgrp.c tcsendbrk.c \
--- libc-sparc-5.3.12.orig/libc/posix/getenvsec.c
+++ libc-sparc-5.3.12/libc/posix/getenvsec.c
@@ -0,0 +1,39 @@
+/* 
+ * This file is hereby placed in the public domain.
+ * David A. Holland, Sep. 1996
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <gnu-stabs.h>
+
+static int __saved_uid=-1;
+static int __trust_environ=0;
+
+static void __init_getenv(int argc, char **argv, char **envp)
+{
+  /*
+   * At program startup, euid==saved uid. (Later on, it may not be.)
+   */
+  __saved_uid = geteuid();
+
+  /*
+   * If we are not running setuid and not running setgid, permit libc
+   * to trust the environment. (We should probably check the supplementary
+   * groups list too.)
+   */
+  if (getuid() == __saved_uid && getgid()==getegid())
+    __trust_environ = 1;
+}
+
+char *__libc_secure_getenv(const char *name)
+{
+  if (__trust_environ)
+    return getenv(name);
+  return NULL;
+}
+
+/*
+ * Call initializer.
+ */
+data_set_element (__libc_subinit, __init_getenv);
--- libc-sparc-5.3.12.orig/libc/pwd/Makefile
+++ libc-sparc-5.3.12/libc/pwd/Makefile
@@ -12,7 +12,7 @@
 SRCS  = fgetpwent.c getpw.c getpwent.c getpwnam.c getpwuid.c \
 	putpwent.c pwdopen.c pwdread.c shadow.c lckpwdf.c
 else
-SRCS= putpwent.c getpw.c
+SRCS= putpwent.c getpw.c lckpwdf.c
 endif
 ASMS= $(SRCS:.c=.s)
 OBJS= $(SRCS:.c=.o)
--- libc-sparc-5.3.12.orig/libc/sbin/lib/sparc/Makefile
+++ libc-sparc-5.3.12/libc/sbin/lib/sparc/Makefile
@@ -0,0 +1,26 @@
+#
+# Makefile for Linux specific functions
+#
+
+TOPDIR=../../..
+
+include $(TOPDIR)/Makeconfig
+include $(TOPDIR)/Makerules
+
+DIRS=crt
+
+lib clean realclean depend::
+ifneq ($(DIRS),)
+	@set -e; for d in $(DIRS); do \
+	  $(MAKE) -C $$d $@; \
+	done
+else
+	@true
+endif
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
--- libc-sparc-5.3.12.orig/libc/sbin/lib/sparc/crt/Makefile
+++ libc-sparc-5.3.12/libc/sbin/lib/sparc/crt/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for crt0.o of Linux
+#
+#
+
+LD=true
+MV=true
+
+TOPDIR=../../../..
+
+include $(TOPDIR)/Makeconfig
+include $(TOPDIR)/Makerules
+
+all lib: crt0.o
+
+realclean clean:
+	$(RM) -f core *.o *.a tmp_make foo
+
+depend:
+	@echo No dependency in $(SUBDIR).
--- libc-sparc-5.3.12.orig/libc/sbin/lib/sparc/crt/crt0.S
+++ libc-sparc-5.3.12/libc/sbin/lib/sparc/crt/crt0.S
@@ -0,0 +1,3 @@
+	.text
+__entry:
+	
--- libc-sparc-5.3.12.orig/libc/string/Makefile
+++ libc-sparc-5.3.12/libc/string/Makefile
@@ -16,13 +16,14 @@
 	memcpy.c memfrob.c memmem.c memmove.c strcasecmp.c \
 	strcoll.c strcpy.c strdup.c strerror.c strfry.c \
 	strncscmp.c strncat.c strncpy.c strsep.c strsignal.c \
+	index.c memccpy.c rindex.c errlist.c siglist.c stpncpy.c \
 	strtok.c strxfrm.c swab.c # __stpncpy.c stpcpy.c strstr.c
 # bzero.c ffs.c memchr.c memcmp.c memset.c strcat.c strchr.c strcmp.c
 # strcspn.c strlen.c strncmp.c strpbrk.c strrchr.c strspn.c strstr.c.
 # 
-SRC2S= index.c memccpy.c rindex.c errlist.c siglist.c stpncpy.c
+SRC2S= 	
 
-SRCS= $(SRC1S) $(SRC2S)
+SRCS= $(SRC1S) $(SRC2S) 
 ASMS= $(SRC1S:.c=.s) $(SRC2S:.c=.s)
 OBJS= $(SRC1S:.c=.o)
 ALIASES= $(SRC2S:.c=.o)
--- libc-sparc-5.3.12.orig/libc/sysdeps/generic/longlong.h
+++ libc-sparc-5.3.12/libc/sysdeps/generic/longlong.h
@@ -1254,6 +1254,7 @@
 const
 #endif
 unsigned char __clz_tab[];
+#define __WANT_CLZ_TAB
 #define count_leading_zeros(count, x) \
   do {									\
     UWtype __xr = (x);							\
--- libc-sparc-5.3.12.orig/libc/sysdeps/generic/dbl2mpn.c
+++ libc-sparc-5.3.12/libc/sysdeps/generic/dbl2mpn.c
@@ -0,0 +1,107 @@
+/* Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "ieee754.h"
+#include <float.h>
+#include <stdlib.h>
+
+/* Convert a `double' in IEEE754 standard double-precision format to a
+   multi-precision integer representing the significand scaled up by its
+   number of bits (52 for double) and an integral power of two (MPN frexp). */
+
+mp_size_t
+__mpn_extract_double (mp_ptr res_ptr, mp_size_t size,
+		      int *expt, int *is_neg,
+		      double value)
+{
+  union ieee754_double u;
+  u.d = value;
+
+  *is_neg = u.ieee.negative;
+  *expt = (int) u.ieee.exponent - IEEE754_DOUBLE_BIAS;
+
+#if BITS_PER_MP_LIMB == 32
+  res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction.  */
+  res_ptr[1] = u.ieee.mantissa0; /* High-order 20 bits.  */
+  #define N 2
+#elif BITS_PER_MP_LIMB == 64
+  /* Hopefully the compiler will combine the two bitfield extracts
+     and this composition into just the original quadword extract.  */
+  res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+  #define N 1
+#else
+  #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+/* The format does not fill the last limb.  There are some zeros.  */
+#define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \
+			   - (DBL_MANT_DIG - ((N - 1) * BITS_PER_MP_LIMB)))
+
+  if (u.ieee.exponent == 0)
+    {
+      /* A biased exponent of zero is a special case.
+	 Either it is a zero or it is a denormal number.  */
+      if (res_ptr[0] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=2.  */
+	/* It's zero.  */
+	*expt = 0;
+      else
+	{
+          /* It is a denormal number, meaning it has no implicit leading
+	     one bit, and its exponent is in fact the format minimum.  */
+	  int cnt;
+
+	  if (res_ptr[N - 1] != 0)
+	    {
+	      count_leading_zeros (cnt, res_ptr[N - 1]);
+	      cnt -= NUM_LEADING_ZEROS;
+#if N == 2
+	      res_ptr[N - 1] = res_ptr[1] << cnt
+			       | (N - 1)
+			         * (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt));
+	      res_ptr[0] <<= cnt;
+#else
+	      res_ptr[N - 1] <<= cnt;
+#endif
+	      *expt = DBL_MIN_EXP - 1 - cnt;
+	    }
+	  else
+	    {
+	      count_leading_zeros (cnt, res_ptr[0]);
+	      if (cnt >= NUM_LEADING_ZEROS)
+		{
+		  res_ptr[N - 1] = res_ptr[0] << (cnt - NUM_LEADING_ZEROS);
+		  res_ptr[0] = 0;
+		}
+	      else
+		{
+		  res_ptr[N - 1] = res_ptr[0] >> (NUM_LEADING_ZEROS - cnt);
+		  res_ptr[0] <<= BITS_PER_MP_LIMB - (NUM_LEADING_ZEROS - cnt);
+		}
+	      *expt = DBL_MIN_EXP - 1
+		      - (BITS_PER_MP_LIMB - NUM_LEADING_ZEROS) - cnt;
+	    }
+	}
+    }
+  else
+    /* Add the implicit leading one bit for a normalized number.  */
+    res_ptr[N - 1] |= 1L << (DBL_MANT_DIG - 1 - ((N - 1) * BITS_PER_MP_LIMB));
+
+  return N;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/generic/ldbl2mpn.c
+++ libc-sparc-5.3.12/libc/sysdeps/generic/ldbl2mpn.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "ieee754.h"
+#include <float.h>
+#include <stdlib.h>
+
+/* Convert a `long double' in IEEE854 standard double-precision format to a
+   multi-precision integer representing the significand scaled up by its
+   number of bits (64 for long double) and an integral power of two
+   (MPN frexpl). */
+
+mp_size_t
+__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
+			   int *expt, int *is_neg,
+			   long double value)
+{
+  union ieee854_long_double u;
+  u.d = value;
+
+  *is_neg = u.ieee.negative;
+  *expt = (int) u.ieee.exponent - IEEE854_LONG_DOUBLE_BIAS;
+
+#if BITS_PER_MP_LIMB == 32
+  res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction.  */
+  res_ptr[1] = u.ieee.mantissa0; /* High-order 32 bits.  */
+  #define N 2
+#elif BITS_PER_MP_LIMB == 64
+  /* Hopefully the compiler will combine the two bitfield extracts
+     and this composition into just the original quadword extract.  */
+  res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+  #define N 1
+#else
+  #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+  if (u.ieee.exponent == 0)
+    {
+      /* A biased exponent of zero is a special case.
+	 Either it is a zero or it is a denormal number.  */
+      if (res_ptr[0] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=2.  */
+	/* It's zero.  */
+	*expt = 0;
+      else
+	{
+          /* It is a denormal number, meaning it has no implicit leading
+  	     one bit, and its exponent is in fact the format minimum.  */
+	  int cnt;
+
+	  /* One problem with Intel's 80-bit format is that the explicit
+	     leading one in the normalized representation has to be zero
+	     for denormalized number.  If it is one, the number is according
+	     to Intel's specification an invalid number.  We make the
+	     representation unique by explicitly clearing this bit.  */
+	  res_ptr[N - 1] &= ~(1L << ((LDBL_MANT_DIG - 1) % BITS_PER_MP_LIMB));
+
+	  if (res_ptr[N - 1] != 0)
+	    {
+	      count_leading_zeros (cnt, res_ptr[N - 1]);
+	      if (cnt != 0)
+		{
+#if N == 2
+	          res_ptr[N - 1] = res_ptr[N - 1] << cnt
+			           | (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt));
+	          res_ptr[0] <<= cnt;
+#else
+	          res_ptr[N - 1] <<= cnt;
+#endif
+		}
+	      *expt = LDBL_MIN_EXP - 1 - cnt;
+	    }
+	  else
+	    {
+	      count_leading_zeros (cnt, res_ptr[0]);
+	      res_ptr[N - 1] = res_ptr[0] << cnt;
+	      res_ptr[0] = 0;
+	      *expt = LDBL_MIN_EXP - 1 - BITS_PER_MP_LIMB - cnt;
+	    }
+	}
+    }
+
+  return N;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/generic/mpn2dbl.c
+++ libc-sparc-5.3.12/libc/sysdeps/generic/mpn2dbl.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "ieee754.h"
+#include <float.h>
+
+/* Convert a multi-precision integer of the needed number of bits (53 for
+   double) and an integral power of two to a `double' in IEEE754 double-
+   precision format.  */
+
+double
+__mpn_construct_double (mp_srcptr frac_ptr, int expt, int negative)
+{
+  union ieee754_double u;
+
+  u.ieee.negative = negative;
+  u.ieee.exponent = expt + IEEE754_DOUBLE_BIAS;
+#if BITS_PER_MP_LIMB == 32
+  u.ieee.mantissa1 = frac_ptr[0];
+  u.ieee.mantissa0 = frac_ptr[1] & ((1 << (DBL_MANT_DIG - 32)) - 1);
+#elif BITS_PER_MP_LIMB == 64
+  u.ieee.mantissa1 = frac_ptr[0] & ((1L << 32) - 1);
+  u.ieee.mantissa0 = (frac_ptr[0] >> 32) & ((1 << (DBL_MANT_DIG - 32)) - 1);
+#else
+  #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+  return u.d;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/generic/mpn2flt.c
+++ libc-sparc-5.3.12/libc/sysdeps/generic/mpn2flt.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "ieee754.h"
+#include <float.h>
+
+/* Convert a multi-precision integer of the needed number of bits (24 for
+   float) and an integral power of two to a `float' in IEEE754 single-
+   precision format.  */ 
+
+float
+__mpn_construct_float (mp_srcptr frac_ptr, int expt, int sign)
+{
+  union ieee754_float u;
+  
+  u.ieee.negative = sign;
+  u.ieee.exponent = expt + IEEE754_FLOAT_BIAS;
+#if BITS_PER_MP_LIMB > FLT_MANT_DIG
+  u.ieee.mantissa = frac_ptr[0] & ((1 << FLT_MANT_DIG) - 1);
+#else
+  #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+  return u.f;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/generic/mpn2ldbl.c
+++ libc-sparc-5.3.12/libc/sysdeps/generic/mpn2ldbl.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "ieee754.h"
+#include <float.h>
+
+/* Convert a multi-precision integer of the needed number of bits (64 for
+   long double) and an integral power of two to a `long double' in IEEE854
+   extended-precision format.  */
+
+long double
+__mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
+{
+  union ieee854_long_double u;
+
+  u.ieee.negative = sign;
+  u.ieee.exponent = expt + IEEE854_LONG_DOUBLE_BIAS;
+#if BITS_PER_MP_LIMB == 32
+  u.ieee.mantissa1 = frac_ptr[0];
+  u.ieee.mantissa0 = frac_ptr[1];
+#elif BITS_PER_MP_LIMB == 64
+  u.ieee.mantissa1 = frac_ptr[0] & ((1L << 32) - 1);
+  u.ieee.mantissa0 = frac_ptr[0] >> 32;
+#else
+  #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+  return u.d;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/Makefile
+++ libc-sparc-5.3.12/libc/sysdeps/Makefile
@@ -10,7 +10,8 @@
 DIRS=$(TARGET_OS)
 
 ifneq ($(MATH),true)
-DIRS := $(DIRS) $(TARGET_ARCH) pthreads
+DIRS := $(DIRS) $(TARGET_ARCH) 
+#pthreads
 endif
 
 lib depend realclean clean:
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/i386/crt/gcrt0.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/i386/crt/gcrt0.S
@@ -2,6 +2,8 @@
  * Copyright (c) 1993 Eric Youngdale, Peter MacDonald, David Engel
  * and Hongjiu Lu.
  *
+ * Copyrigh (c) 1996 Miguel de Icaza.
+ *
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -62,12 +64,6 @@
 #define	V_ETEXT	$_etext
 #define	V_ENTRY	$_start
 #define V_MCLEANUP $_mcleanup
-#ifdef __i486__
-#define ALIGN_TEXT	.align	16,0x90
-#else
-#define ALIGN_TEXT	.align	4,0x90
-#endif
-#define ALIGN_DATA	.align	4
 #else
 #define MAIN _main
 #define ATEXIT _atexit
@@ -82,20 +78,14 @@
 #define	V_ETEXT	$_etext
 #define	V_ENTRY	$__entry
 #define V_MCLEANUP $__mcleanup
-#ifdef __i486__
-#define ALIGN_TEXT	.align	4,0x90
-#else
-#define ALIGN_TEXT	.align	2,0x90
-#endif
-#define ALIGN_DATA	.align	2
 #endif
 
 	.file "gcrt0.S"
 
 #if defined(__ELF__) && defined(CALL_DEFAULT_LOCALE)
-	.section .rodata
-	ALIGN_DATA
-	.type ___null_string,@object
+	.section ".rodata"
+	.align 4
+	.type ___null_string,object
 	.size ___null_string,4
 ___null_string:
 	.long .L_shared_dummy__
@@ -104,9 +94,9 @@
 #endif
 
 	.text
-	ALIGN_TEXT
 	.globl	___crt_dummy__
 ___crt_dummy__:
+
 #ifndef __ELF__
 __entry:
 /*
@@ -117,7 +107,7 @@
 #else
 /* ELF stuff here */
 .globl _start
-.type _start,@function
+.type _start,func
 _start:
 	/* First locate the start of the environment variables */
 	popl %ecx
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/i386/Makefile
+++ libc-sparc-5.3.12/libc/sysdeps/linux/i386/Makefile
@@ -27,7 +27,7 @@
 SRC1S = __brk.c  __sbrk.c __select.c __sigact.c getprio.c \
 	ptrace.c readdir.c sigsuspend.c libc_exit.c \
 	__setfpucw.c __fpu_control.c __init_brk.c readdir_r.c \
-	__getfpucw.c
+	_errlist.c
 # __load.c __adjtime.c __ntpgttm.c __wait.c __wait3.c __waitpid.c
 # accept.c bind.c msgget.c msgrcv.c msgsnd.c msgctl.c semget.c
 # semop.c semctl.c listen.c mmap.c socket.c socketpair.c tell.c
@@ -35,7 +35,7 @@
 # shutdown.c connect.c getpeernam.c getsocknam.c getsockopt.c
 # shmget.c shmat.c shmdt.c shmctl.c
 #SRC2S = __vfork.c vfork.c
-SRC3S = ____sig.S syscall.S # __adjtimex.S
+SRC3S = ____sig.S syscall.S __pipe.S __fork.S # __adjtimex.S 
 
 SRCS= $(SRC1S) $(SRC2S) $(SRC3S)
 ASMS= $(SRC1S:.c=.s) $(SRC2S:.c=.s) $(SRC3S:.S=.s)
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/i386/__fork.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/i386/__fork.S
@@ -0,0 +1,56 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <sysdep.h>
+
+SYSCALL__ (fork, 0)
+	ret
+
+#ifdef __ELF__
+
+#ifdef _POSIX_THREADS
+
+#ifdef PTHREAD_KERNEL
+
+.globl __machdep_sys_vfork
+__machdep_sys_vfork=__machdep_sys_fork
+
+.weak machdep_sys_vfork
+machdep_sys_vfork=__machdep_sys_fork
+
+#else
+
+.weak __vfork
+__vfork=__fork;
+
+.weak vfork
+vfork=__fork;
+
+#endif
+
+#else /* _POSIX_THREADS */
+
+.globl __vfork
+__vfork=__fork;
+
+.globl vfork
+vfork=__fork;
+
+#endif /* _POSIX_THREADS */
+
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/i386/__pipe.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/i386/__pipe.S
@@ -0,0 +1,22 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <sysdep.h>
+
+SYSCALL__ (pipe, 1)
+	ret
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/i386/_errlist.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/i386/_errlist.c
@@ -0,0 +1,145 @@
+#include <ansidecl.h>
+#include <stddef.h>
+#if 0
+#include <errno.h>
+#endif
+
+/* This is a list of all known signal numbers.  */
+
+CONST char *CONST _sys_errlist[] = {
+	"Unknown error",			/* 0 */
+	"Operation not permitted", 		/* EPERM */
+	"No such file or directory", 		/* ENOENT */
+	"No such process", 			/* ESRCH */
+	"Interrupted system call", 		/* EINTR */
+	"I/O error", 				/* EIO */
+	"No such device or address", 		/* ENXIO */
+	"Arg list too long", 			/* E2BIG */
+	"Exec format error", 			/* ENOEXEC */
+	"Bad file number", 			/* EBADF */
+	"No child processes", 			/* ECHILD */
+	"Try again", 				/* EAGAIN */
+	"Out of memory", 			/* ENOMEM */
+	"Permission denied", 			/* EACCES */
+	"Bad address", 				/* EFAULT */
+	"Block device required", 		/* ENOTBLK */
+	"Device or resource busy", 		/* EBUSY */
+	"File exists", 				/* EEXIST */
+	"Cross-device link", 			/* EXDEV */
+	"No such device", 			/* ENODEV */
+	"Not a directory", 			/* ENOTDIR */
+	"Is a directory", 			/* EISDIR */
+	"Invalid argument", 			/* EINVAL */
+	"File table overflow", 			/* ENFILE */
+	"Too many open files", 			/* EMFILE */
+	"Not a typewriter", 			/* ENOTTY */
+	"Text file busy", 			/* ETXTBSY */
+	"File too large", 			/* EFBIG */
+	"No space left on device", 		/* ENOSPC */
+	"Illegal seek", 			/* ESPIPE */
+	"Read-only file system", 		/* EROFS */
+	"Too many links", 			/* EMLINK */
+	"Broken pipe", 				/* EPIPE */
+	"Math argument out of domain of func", 	/* EDOM */
+	"Math result not representable", 	/* ERANGE */
+	"Resource deadlock would occur", 	/* EDEADLK */
+	"File name too long", 			/* ENAMETOOLONG */
+	"No record locks available", 		/* ENOLCK */
+	"Function not implemented", 		/* ENOSYS */
+	"Directory not empty", 			/* ENOTEMPTY */
+	"Too many symbolic links encountered", 	/* ELOOP */
+	"Operation would block", 		/* EWOULDBLOCK */
+	"No message of desired type", 		/* ENOMSG */
+	"Identifier removed", 			/* EIDRM */
+	"Channel number out of range", 		/* ECHRNG */
+	"Level 2 not synchronized", 		/* EL2NSYNC */
+	"Level 3 halted", 			/* EL3HLT */
+	"Level 3 reset", 			/* EL3RST */
+	"Link number out of range", 		/* ELNRNG */
+	"Protocol driver not attached", 	/* EUNATCH */
+	"No CSI structure available", 		/* ENOCSI */
+	"Level 2 halted", 			/* EL2HLT */
+	"Invalid exchange", 			/* EBADE */
+	"Invalid request descriptor", 		/* EBADR */
+	"Exchange full", 			/* EXFULL */
+	"No anode", 				/* ENOANO */
+	"Invalid request code", 		/* EBADRQC */
+	"Invalid slot", 			/* EBADSLT */
+	"File locking deadlock error", 		/* EDEADLOCK */
+	"Bad font file format", 		/* EBFONT */
+	"Device not a stream", 			/* ENOSTR */
+	"No data available", 			/* ENODATA */
+	"Timer expired", 			/* ETIME */
+	"Out of streams resources", 		/* ENOSR */
+	"Machine is not on the network", 	/* ENONET */
+	"Package not installed", 		/* ENOPKG */
+	"Object is remote", 			/* EREMOTE */
+	"Link has been severed", 		/* ENOLINK */
+	"Advertise error", 			/* EADV */
+	"Srmount error", 			/* ESRMNT */
+	"Communication error on send", 		/* ECOMM */
+	"Protocol error", 			/* EPROTO */
+	"Multihop attempted", 			/* EMULTIHOP */
+	"RFS specific error", 			/* EDOTDOT */
+	"Not a data message", 			/* EBADMSG */
+	"Value too large for defined data type", 	/* EOVERFLOW */
+	"Name not unique on network", 		/* ENOTUNIQ */
+	"File descriptor in bad state", 	/* EBADFD */
+	"Remote address changed", 		/* EREMCHG */
+	"Can not access a needed shared library", 	/* ELIBACC */
+	"Accessing a corrupted shared library", 	/* ELIBBAD */
+	".lib section in a.out corrupted", 	/* ELIBSCN */
+	"Attempting to link in too many shared libraries", 	/* ELIBMAX */
+	"Cannot exec a shared library directly", 	/* ELIBEXEC */
+	"Illegal byte sequence", 		/* EILSEQ */
+	"Interrupted system call should be restarted", 	/* ERESTART */
+	"Streams pipe error", 			/* ESTRPIPE */
+	"Too many users", 			/* EUSERS */
+	"Socket operation on non-socket", 	/* ENOTSOCK */
+	"Destination address required", 	/* EDESTADDRREQ */
+	"Message too long", 			/* EMSGSIZE */
+	"Protocol wrong type for socket", 	/* EPROTOTYPE */
+	"Protocol not available", 		/* ENOPROTOOPT */
+	"Protocol not supported", 		/* EPROTONOSUPPORT */
+	"Socket type not supported", 		/* ESOCKTNOSUPPORT */
+	"Operation not supported on transport endpoint", 	/* EOPNOTSUPP */
+	"Protocol family not supported", 	/* EPFNOSUPPORT */
+	"Address family not supported by protocol", 	/* EAFNOSUPPORT */
+	"Address already in use", 		/* EADDRINUSE */
+	"Cannot assign requested address", 	/* EADDRNOTAVAIL */
+	"Network is down", 			/* ENETDOWN */
+	"Network is unreachable", 		/* ENETUNREACH */
+	"Network dropped connection because of reset", 	/* ENETRESET */
+	"Software caused connection abort", 	/* ECONNABORTED */
+	"Connection reset by peer", 		/* ECONNRESET */
+	"No buffer space available", 		/* ENOBUFS */
+	"Transport endpoint is already connected", 	/* EISCONN */
+	"Transport endpoint is not connected", 	/* ENOTCONN */
+	"Cannot send after transport endpoint shutdown", 	/* ESHUTDOWN */
+	"Too many references: cannot splice", 	/* ETOOMANYREFS */
+	"Connection timed out", 		/* ETIMEDOUT */
+	"Connection refused", 			/* ECONNREFUSED */
+	"Host is down", 			/* EHOSTDOWN */
+	"No route to host", 			/* EHOSTUNREACH */
+	"Operation already in progress", 	/* EALREADY */
+	"Operation now in progress", 		/* EINPROGRESS */
+	"Stale NFS file handle", 		/* ESTALE */
+	"Structure needs cleaning", 		/* EUCLEAN */
+	"Not a XENIX named type file", 		/* ENOTNAM */
+	"No XENIX semaphores available", 	/* ENAVAIL */
+	"Is a named type file", 		/* EISNAM */
+	"Remote I/O error", 			/* EREMOTEIO */
+	"Quota exceeded", 			/* EDQUOT */
+	NULL
+};
+
+
+#define NR_ERRORS ((sizeof (_sys_errlist))/(sizeof(char *))-1)
+
+CONST int _sys_nerr = NR_ERRORS;
+
+#include <gnu-stabs.h>
+#ifdef weak_alias
+weak_alias (_sys_errlist, sys_errlist);
+weak_alias (_sys_nerr, sys_nerr);
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/m68k/Makefile
+++ libc-sparc-5.3.12/libc/sysdeps/linux/m68k/Makefile
@@ -24,7 +24,8 @@
 
 SRC1S = __brk.c  __sbrk.c __select.c __sigact.c getprio.c \
 	ptrace.c readdir.c sigsuspend.c syscall.c libc_exit.c \
-	__setfpucw.c __fpu_control.c __init_brk.c readdir_r.c
+	__setfpucw.c __fpu_control.c __init_brk.c readdir_r.c \
+	_errlist.c
 # __load.c __adjtime.c __ntpgttm.c __wait.c __wait3.c __waitpid.c
 # accept.c bind.c msgget.c msgrcv.c msgsnd.c msgctl.c semget.c
 # semop.c semctl.c listen.c mmap.c socket.c socketpair.c tell.c
@@ -32,7 +33,7 @@
 # shutdown.c connect.c getpeernam.c getsocknam.c getsockopt.c
 # shmget.c shmat.c shmdt.c shmctl.c
 #SRC2S = __vfork.c vfork.c
-SRC3S = ____sig.S # __adjtimex.S
+SRC3S = __fork.S __pipe.S ____sig.S # __adjtimex.S
 
 SRCS= $(SRC1S) $(SRC2S) $(SRC3S)
 ASMS= $(SRC1S:.c=.s) $(SRC2S:.c=.s) $(SRC3S:.S=.s)
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/m68k/__fork.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/m68k/__fork.S
@@ -0,0 +1,56 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <sysdep.h>
+
+SYSCALL__ (fork, 0)
+	ret
+
+#ifdef __ELF__
+
+#ifdef _POSIX_THREADS
+
+#ifdef PTHREAD_KERNEL
+
+.globl __machdep_sys_vfork
+__machdep_sys_vfork=__machdep_sys_fork
+
+.weak machdep_sys_vfork
+machdep_sys_vfork=__machdep_sys_fork
+
+#else
+
+.weak __vfork
+__vfork=__fork;
+
+.weak vfork
+vfork=__fork;
+
+#endif
+
+#else /* _POSIX_THREADS */
+
+.globl __vfork
+__vfork=__fork;
+
+.globl vfork
+vfork=__fork;
+
+#endif /* _POSIX_THREADS */
+
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/m68k/__pipe.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/m68k/__pipe.S
@@ -0,0 +1,22 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <sysdep.h>
+
+SYSCALL__ (pipe, 1)
+	ret
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/m68k/_errlist.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/m68k/_errlist.c
@@ -0,0 +1,145 @@
+#include <ansidecl.h>
+#include <stddef.h>
+#if 0
+#include <errno.h>
+#endif
+
+/* This is a list of all known signal numbers.  */
+
+CONST char *CONST _sys_errlist[] = {
+	"Unknown error",			/* 0 */
+	"Operation not permitted", 		/* EPERM */
+	"No such file or directory", 		/* ENOENT */
+	"No such process", 			/* ESRCH */
+	"Interrupted system call", 		/* EINTR */
+	"I/O error", 				/* EIO */
+	"No such device or address", 		/* ENXIO */
+	"Arg list too long", 			/* E2BIG */
+	"Exec format error", 			/* ENOEXEC */
+	"Bad file number", 			/* EBADF */
+	"No child processes", 			/* ECHILD */
+	"Try again", 				/* EAGAIN */
+	"Out of memory", 			/* ENOMEM */
+	"Permission denied", 			/* EACCES */
+	"Bad address", 				/* EFAULT */
+	"Block device required", 		/* ENOTBLK */
+	"Device or resource busy", 		/* EBUSY */
+	"File exists", 				/* EEXIST */
+	"Cross-device link", 			/* EXDEV */
+	"No such device", 			/* ENODEV */
+	"Not a directory", 			/* ENOTDIR */
+	"Is a directory", 			/* EISDIR */
+	"Invalid argument", 			/* EINVAL */
+	"File table overflow", 			/* ENFILE */
+	"Too many open files", 			/* EMFILE */
+	"Not a typewriter", 			/* ENOTTY */
+	"Text file busy", 			/* ETXTBSY */
+	"File too large", 			/* EFBIG */
+	"No space left on device", 		/* ENOSPC */
+	"Illegal seek", 			/* ESPIPE */
+	"Read-only file system", 		/* EROFS */
+	"Too many links", 			/* EMLINK */
+	"Broken pipe", 				/* EPIPE */
+	"Math argument out of domain of func", 	/* EDOM */
+	"Math result not representable", 	/* ERANGE */
+	"Resource deadlock would occur", 	/* EDEADLK */
+	"File name too long", 			/* ENAMETOOLONG */
+	"No record locks available", 		/* ENOLCK */
+	"Function not implemented", 		/* ENOSYS */
+	"Directory not empty", 			/* ENOTEMPTY */
+	"Too many symbolic links encountered", 	/* ELOOP */
+	"Operation would block", 		/* EWOULDBLOCK */
+	"No message of desired type", 		/* ENOMSG */
+	"Identifier removed", 			/* EIDRM */
+	"Channel number out of range", 		/* ECHRNG */
+	"Level 2 not synchronized", 		/* EL2NSYNC */
+	"Level 3 halted", 			/* EL3HLT */
+	"Level 3 reset", 			/* EL3RST */
+	"Link number out of range", 		/* ELNRNG */
+	"Protocol driver not attached", 	/* EUNATCH */
+	"No CSI structure available", 		/* ENOCSI */
+	"Level 2 halted", 			/* EL2HLT */
+	"Invalid exchange", 			/* EBADE */
+	"Invalid request descriptor", 		/* EBADR */
+	"Exchange full", 			/* EXFULL */
+	"No anode", 				/* ENOANO */
+	"Invalid request code", 		/* EBADRQC */
+	"Invalid slot", 			/* EBADSLT */
+	"File locking deadlock error", 		/* EDEADLOCK */
+	"Bad font file format", 		/* EBFONT */
+	"Device not a stream", 			/* ENOSTR */
+	"No data available", 			/* ENODATA */
+	"Timer expired", 			/* ETIME */
+	"Out of streams resources", 		/* ENOSR */
+	"Machine is not on the network", 	/* ENONET */
+	"Package not installed", 		/* ENOPKG */
+	"Object is remote", 			/* EREMOTE */
+	"Link has been severed", 		/* ENOLINK */
+	"Advertise error", 			/* EADV */
+	"Srmount error", 			/* ESRMNT */
+	"Communication error on send", 		/* ECOMM */
+	"Protocol error", 			/* EPROTO */
+	"Multihop attempted", 			/* EMULTIHOP */
+	"RFS specific error", 			/* EDOTDOT */
+	"Not a data message", 			/* EBADMSG */
+	"Value too large for defined data type", 	/* EOVERFLOW */
+	"Name not unique on network", 		/* ENOTUNIQ */
+	"File descriptor in bad state", 	/* EBADFD */
+	"Remote address changed", 		/* EREMCHG */
+	"Can not access a needed shared library", 	/* ELIBACC */
+	"Accessing a corrupted shared library", 	/* ELIBBAD */
+	".lib section in a.out corrupted", 	/* ELIBSCN */
+	"Attempting to link in too many shared libraries", 	/* ELIBMAX */
+	"Cannot exec a shared library directly", 	/* ELIBEXEC */
+	"Illegal byte sequence", 		/* EILSEQ */
+	"Interrupted system call should be restarted", 	/* ERESTART */
+	"Streams pipe error", 			/* ESTRPIPE */
+	"Too many users", 			/* EUSERS */
+	"Socket operation on non-socket", 	/* ENOTSOCK */
+	"Destination address required", 	/* EDESTADDRREQ */
+	"Message too long", 			/* EMSGSIZE */
+	"Protocol wrong type for socket", 	/* EPROTOTYPE */
+	"Protocol not available", 		/* ENOPROTOOPT */
+	"Protocol not supported", 		/* EPROTONOSUPPORT */
+	"Socket type not supported", 		/* ESOCKTNOSUPPORT */
+	"Operation not supported on transport endpoint", 	/* EOPNOTSUPP */
+	"Protocol family not supported", 	/* EPFNOSUPPORT */
+	"Address family not supported by protocol", 	/* EAFNOSUPPORT */
+	"Address already in use", 		/* EADDRINUSE */
+	"Cannot assign requested address", 	/* EADDRNOTAVAIL */
+	"Network is down", 			/* ENETDOWN */
+	"Network is unreachable", 		/* ENETUNREACH */
+	"Network dropped connection because of reset", 	/* ENETRESET */
+	"Software caused connection abort", 	/* ECONNABORTED */
+	"Connection reset by peer", 		/* ECONNRESET */
+	"No buffer space available", 		/* ENOBUFS */
+	"Transport endpoint is already connected", 	/* EISCONN */
+	"Transport endpoint is not connected", 	/* ENOTCONN */
+	"Cannot send after transport endpoint shutdown", 	/* ESHUTDOWN */
+	"Too many references: cannot splice", 	/* ETOOMANYREFS */
+	"Connection timed out", 		/* ETIMEDOUT */
+	"Connection refused", 			/* ECONNREFUSED */
+	"Host is down", 			/* EHOSTDOWN */
+	"No route to host", 			/* EHOSTUNREACH */
+	"Operation already in progress", 	/* EALREADY */
+	"Operation now in progress", 		/* EINPROGRESS */
+	"Stale NFS file handle", 		/* ESTALE */
+	"Structure needs cleaning", 		/* EUCLEAN */
+	"Not a XENIX named type file", 		/* ENOTNAM */
+	"No XENIX semaphores available", 	/* ENAVAIL */
+	"Is a named type file", 		/* EISNAM */
+	"Remote I/O error", 			/* EREMOTEIO */
+	"Quota exceeded", 			/* EDQUOT */
+	NULL
+};
+
+
+#define NR_ERRORS ((sizeof (_sys_errlist))/(sizeof(char *))-1)
+
+CONST int _sys_nerr = NR_ERRORS;
+
+#include <gnu-stabs.h>
+#ifdef weak_alias
+weak_alias (_sys_errlist, sys_errlist);
+weak_alias (_sys_nerr, sys_nerr);
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/Makefile
+++ libc-sparc-5.3.12/libc/sysdeps/linux/Makefile
@@ -26,7 +26,7 @@
 SRC1S= __bsd_sig.c __flock.c __fpathconf.c __getdtsz.c \
 	__gethstnm.c __getpgsz.c __isatty.c __pathconf.c \
 	__sigblock.c __siggtmsk.c __sigpause.c __sigstmsk.c \
-	__sysconf.c __tcgetatr.c __utimes.c _errlist.c _siglist.c \
+	__sysconf.c __tcgetatr.c __utimes.c _siglist.c \
 	getdnnm.c mkfifo.c setegid.c \
 	seteuid.c signal.c \
 	__adjtime.c __ntpgttm.c __wait.c __wait3.c \
@@ -46,11 +46,11 @@
 	sysctl.c
 SRC2S=	__access.S __chdir.S __chmod.S __chown.S __close.S __dup.S \
 	__dup2.S __execve.S __fchmod.S __fchdir.S __fchown.S __fcntl.S \
-	__fork.S __fstatfs.S __getegid.S __geteuid.S \
+	__fstatfs.S __getegid.S __geteuid.S \
 	__getgid.S __getgrps.S __getitmr.S __getpid.S __getppid.S \
 	__getrusag.S __gettod.S __getuid.S __ioctl.S __kill.S \
 	__link.S __lseek.S __mkdir.S __open.S \
-	__pipe.S __read.S __readlink.S __rmdir.S __setgid.S \
+	__read.S __readlink.S __rmdir.S __setgid.S \
 	__setitmr.S __setregid.S __setreuid.S __setsid.S __settod.S \
 	__setuid.S __sigproc.S __statfs.S \
 	__symlink.S __times.S __umask.S __uname.S __unlink.S \
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/__access.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/__access.S
@@ -20,3 +20,4 @@
 
 SYSCALL__ (access, 2)
 	ret
+
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/__adjtime.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/__adjtime.c
@@ -3,7 +3,7 @@
 #include <errno.h>
 #include <limits.h>
 #include <linux/timex.h>
-
+#include <asm/unistd.h>
 #ifdef __SVR4_I386_ABI_L1__
 #define adjtimex __adjtimex
 #else
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/__fork.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/__fork.S
@@ -1,56 +0,0 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <sysdep.h>
-
-SYSCALL__ (fork, 0)
-	ret
-
-#ifdef __ELF__
-
-#ifdef _POSIX_THREADS
-
-#ifdef PTHREAD_KERNEL
-
-.globl __machdep_sys_vfork
-__machdep_sys_vfork=__machdep_sys_fork
-
-.weak machdep_sys_vfork
-machdep_sys_vfork=__machdep_sys_fork
-
-#else
-
-.weak __vfork
-__vfork=__fork;
-
-.weak vfork
-vfork=__fork;
-
-#endif
-
-#else /* _POSIX_THREADS */
-
-.globl __vfork
-__vfork=__fork;
-
-.globl vfork
-vfork=__fork;
-
-#endif /* _POSIX_THREADS */
-
-#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/__pipe.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/__pipe.S
@@ -1,22 +0,0 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <sysdep.h>
-
-SYSCALL__ (pipe, 1)
-	ret
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/_siglist.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/_siglist.c
@@ -4,7 +4,6 @@
 
 
 /* This is a list of all known signal numbers.  */
-
 CONST char *CONST _sys_siglist[] =
   {
     "Unknown signal",
@@ -14,6 +13,33 @@
     "Illegal instruction",
     "Trace/breakpoint trap",
     "IOT trap/Abort",
+#ifdef __sparc__
+    "EMT Instruction",		/* 7 */
+    "Floating point exception",	/* 8 */
+    "Killed",			/* 9 */
+    "Bus error",		/* 10 */
+    "Segmentation fault",	/* 11 */
+    "Bad argument to systen call (SunOS)", /* 12 */
+    "Broken pipe",		/* 13 */
+    "Alarm clock",		/* 14 */
+    "Terminated",		/* 15 */
+    "Urgent condition",		/* 16 */
+    "Stopped (signal)",		/* SIGSTOP */
+    "Stopped",			/* SIGTSTP */
+    "Continued",		/* 19 */
+    "Child exited",		/* 20 */
+    "Stopped (tty input)",	/* 21 */
+    "Stopped (tty output)",	/* 22 */
+    "Possible I/O",		/* 23 */
+    "CPU time limit exceeded",	/* 24 */
+    "File size limit exceeded",	/* 25 */
+    "Virtual time alarm",	/* 26 */
+    "Profile signal",		/* 27 */
+    "Window size changed",	/* 28 */
+    "Resource Lost (SunOS)",	/* 29 */
+    "User defined signal 1",	/* 30 */
+    "User defined signal 2",	/* 31 */
+#else
     "Bus error",
     "Floating point exception",
     "Killed",
@@ -40,6 +66,7 @@
     "Power failure",
     "Unused signal",
     NULL
+#endif
   };
 
 #include <gnu-stabs.h>
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/mmap.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/mmap.c
@@ -5,6 +5,37 @@
 
 #define SYS__mmap	SYS_mmap
 
+
+#ifdef __sparc__
+#if 0
+_syscall6(caddr_t,mmap,caddr_t,addr,size_t,len,int,prot,int,flags,int,fd,off_t,off);
+#endif
+
+__ptr_t
+mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, off_t off)
+{
+	caddr_t __res;
+
+	__asm__ __volatile__("mov %1, %%o0\n\t"
+			     "mov %2, %%o1\n\t"
+			     "mov %3, %%o2\n\t"
+			     "mov %4, %%o3\n\t"
+			     "mov %5, %%o4\n\t"
+			     "mov %6, %%o5\n\t"
+			     "mov %7, %%g1\n\t"
+			     "t 0x10\n\t"
+			     "bcc 1f\n\t"
+			     " mov %%o0, %0\n\t"
+			     "sub %%g0, %%o0, %0\n\t"
+			     "1:\n\t" :
+			     "=r" (__res) :
+			     "0" (addr), "r" (len), "r" (prot), "r" (flags),
+			     "r" (fd), "r" (off), "i" (__NR_mmap) :
+			     "g1", "o0", "o1", "o2", "o3", "o4", "o5");
+	return __res;
+}
+
+#else
 static inline
 _syscall1(long,_mmap,unsigned long *,buffer);
 
@@ -21,3 +52,4 @@
 	buffer[5] = (unsigned long)off;
 	return (__ptr_t) _mmap(buffer);
 }
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sysdep.h
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sysdep.h
@@ -37,25 +37,29 @@
 
 /* Use the regular ELF conventions about underscores, and provide the
    weak symbol, as required */
+#define SYSCALL__POST(name, args) \
+	.weak machdep_sys_##name; \
+	machdep_sys_##name = __machdep_sys_##name; \
+	.type __machdep_sys_##name,@function; \
+	.type machdep_sys_##name,@function; \
+	.L__machdep_sys_##name##end: .size __machdep_sys_##name,.L__machdep_sys_##name##end - __machdep_sys_##name
 #define	SYSCALL__(name,args)	PSEUDO (__machdep_sys_##name, name, args) \
-.weak machdep_sys_##name; \
-  machdep_sys_##name = __machdep_sys_##name; \
-.type __machdep_sys_##name,@function; \
-.type machdep_sys_##name,@function; \
-.L__machdep_sys_##name##end: .size __machdep_sys_##name,.L__machdep_sys_##name##end - __machdep_sys_##name
+	SYSCALL__POST(name,args)
 
-#define	SYSCALL(name,args)	PSEUDO (__machdep_sys_##name, name, args) \
+#define SYSCALLPOST(name,args) \
 .weak machdep_sys_##name; \
   machdep_sys_##name = __machdep_sys_##name; \
 .type __machdep_sys_##name,@function; \
 .type machdep_sys_##name,@function; \
 .L__machdep_sys_##name##end: .size __machdep_sys_##name,.L__machdep_sys_##name##end - __machdep_sys_##name
+#define	SYSCALL(name,args)	PSEUDO (__machdep_sys_##name, name, args) \
+        SYSCALLPOST(name,args)
 
 #else /* PTHREAD_KERNEL */
 
 /* Use the regular ELF conventions about underscores, and provide the
    weak symbol, as required */
-#define	SYSCALL__(name,args)	PSEUDO (__libc_##name, name, args) \
+#define SYSCALL__POST(name,args) \
 .weak __##name; \
 .weak name;  \
   __##name = __libc_##name; \
@@ -64,21 +68,25 @@
 .type name,@function; \
 .type __##name,@function; \
 .L__libc_##name##end: .size __libc_##name,.L__libc_##name##end - __libc_##name
+#define	SYSCALL__(name,args)	PSEUDO (__libc_##name, name, args) \
+	SYSCALL__POST(name,args)
 
-#define	SYSCALL(name,args)	PSEUDO (__libc_##name, name, args) \
+#define SYSCALLPOST(name,args) \
 .weak name; \
   name = __libc_##name; \
 .type __libc_##name,@function; \
 .type name,@function; \
 .L__libc_##name##end: .size __libc_##name,.L__libc_##name##end - __libc_##name
-
+#define	SYSCALL(name,args)	PSEUDO (__libc_##name, name, args) \
+	SYSCALLPOST(name,args)
 #endif /* PTHREAD_KERNEL */
 
 #else /* _POSIX_THREADS */
 
 /* Use the regular ELF conventions about underscores, and provide the
    weak symbol, as required */
-#define	SYSCALL__(name,args)	PSEUDO (__libc_##name, name, args) \
+
+#define SYSCALL__POST(name,args) \
 .weak name;  \
   __##name = __libc_##name; \
   name = __libc_##name; \
@@ -86,13 +94,16 @@
 .type name,@function; \
 .type __##name,@function; \
 .L__libc_##name##end: .size __libc_##name,.L__libc_##name##end - __libc_##name
+#define	SYSCALL__(name,args)	PSEUDO (__libc_##name, name, args) \
+        SYSCALL__POST(name,args)
 
-#define	SYSCALL(name,args)	PSEUDO (__libc_##name, name, args) \
+#define SYSCALLPOST(name,args) \
   name = __libc_##name; \
 .type __libc_##name,@function; \
 .type name,@function; \
 .L__libc_##name##end: .size __libc_##name,.L__libc_##name##end - __libc_##name
-
+#define	SYSCALL(name,args)	PSEUDO (__libc_##name, name, args) \
+	SYSCALL__POST(name,args)
 #endif /* _POSIX_THREADS */
 
 #else /* __ELF__ */
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/Makefile
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/Makefile
@@ -0,0 +1,65 @@
+#
+# Makefile of Linux specific functions for sparc
+#
+
+TOPDIR=../../..
+
+include $(TOPDIR)/Makeconfig
+include $(TOPDIR)/Makerules
+
+INC_CFLAGS=-I$(TOPDIR) -I.
+
+ifeq ($(MATH),true)
+
+lib all:
+	($(MAKE) -C math $@)
+else
+
+ifneq ($(LITE),true)
+DIRS:=math crt
+endif
+
+ifeq ($(PROFILE),true)
+DIRS:=$(DIRS) gmon
+endif
+
+# 
+SRC1S = readdir.c _errlist.c sigsuspend.c getprio.c __sigact.c \
+	_errlist.c __init_brk.c __brk.c __sbrk.c libc_exit.c \
+	readdir_r.c libc_exit.c ptrace.c
+
+# __load.c __adjtime.c __ntpgttm.c __wait.c __wait3.c __waitpid.c
+# accept.c bind.c msgget.c msgrcv.c msgsnd.c msgctl.c semget.c
+# semop.c semctl.c listen.c mmap.c socket.c socketpair.c tell.c
+# ulimit.c recv.c revcfrom.c send.c sendto.c setpgrp.c setsockopt.c
+# shutdown.c connect.c getpeernam.c getsocknam.c getsockopt.c
+# shmget.c shmat.c shmdt.c shmctl.c
+#SRC2S = __vfork.c vfork.c __vfork.S
+SRC3S = __fork.S __pipe.S sysdep.S \
+        ____sig.S __select.S syscall.S
+
+
+SRCS= $(SRC1S) $(SRC2S) $(SRC3S)
+ASMS= $(SRC1S:.c=.s) $(SRC2S:.c=.s) $(SRC3S:.S=.s)
+OBJS= $(SRC1S:.c=.o) $(SRC3S:.S=.o)
+ALIASES= $(SRC2S:.c=.o)
+
+include $(TOPDIR)/Maketargets
+
+ifeq ($(STATIC),true)
+
+LIBIEEE=$(STATIC_DIR)/libieee.a
+
+lib:: $(LIBIEEE)
+
+$(STATIC_DIR)/$(SUBDIR)/ieee.o: ieee.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+$(LIBIEEE): $(STATIC_DIR)/$(SUBDIR)/ieee.o
+	$(RM) -f $(LIBIEEE)
+	$(AR) $(AR_FLAGS) $(LIBIEEE) $?
+	$(REALRANLIB) $(LIBIEEE)
+endif
+
+endif
+
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/____sig.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/____sig.S
@@ -0,0 +1,139 @@
+/* trampoline code for signal handling on Linux/SPARC */
+/* Based on the trampoline code of NetBSD/SPARC */
+/* Many thanks go to David Miller for explaining all this to me */
+/* miguel@nuclecu.unam.mx */
+
+#include <sysdep.h>
+
+/* For REGWIN_SZ */
+#include <asm/ptrace.h>
+#include <asm/psr.h>
+
+/* The C compiler frame size */
+#define CCFSZ  96
+
+	.text
+
+ENTRY(____sparc_signal_trampoline)
+	.global SYMBOL_NAME(____sig_table)
+
+	/* Make room for 32 %f registers + %fsr 
+         * this is 132 bytes + alignement = 136
+         * 96 is the C frame size
+         */
+	save  	%sp,-136-CCFSZ,%sp
+
+	/* save regular registers */
+	mov	%g2,%l2
+	mov	%g3,%l3
+	mov	%g4,%l4
+	mov	%g5,%l5
+	mov	%g6,%l6
+	mov	%g7,%l7
+	
+	/* save fpu registers */
+	ld	[%fp+64+16+20],%l0      /* load the psr from sigcontext */
+	sethi	%hi(PSR_EF),%l1         
+	andcc	%l0,%l1,%l0	        /* is floating point enabled?   */
+	be	1f
+	rd	%y,%l1			/* save y anyways */
+
+	/* save fpu registers */
+	st      %fsr, [%sp + CCFSZ + 0]
+        std     %f0, [%sp + CCFSZ + 8]
+        std     %f2, [%sp + CCFSZ + 16]
+        std     %f4, [%sp + CCFSZ + 24]
+        std     %f6, [%sp + CCFSZ + 32]
+        std     %f8, [%sp + CCFSZ + 40]
+        std     %f10, [%sp + CCFSZ + 48]
+        std     %f12, [%sp + CCFSZ + 56]
+        std     %f14, [%sp + CCFSZ + 64]
+        std     %f16, [%sp + CCFSZ + 72]
+        std     %f18, [%sp + CCFSZ + 80]
+        std     %f20, [%sp + CCFSZ + 88]
+        std     %f22, [%sp + CCFSZ + 96]
+        std     %f24, [%sp + CCFSZ + 104]
+        std     %f26, [%sp + CCFSZ + 112]
+        std     %f28, [%sp + CCFSZ + 120]
+        std     %f30, [%sp + CCFSZ + 128]            
+
+1:	
+	/* Load signal number */
+	ld	[%fp + REGWIN_SZ],%o0
+	mov	%fp,%o1
+	mov	0xfea,%o2
+
+	/* Sanity check */
+	cmp	%o0,33
+	bl	1f
+	or	%g0,%g0,%g1	/*Call sys_setup */
+	t	0x10
+1:
+#ifdef __PIC__ 
+	/* Save return address */
+	mov	%o7,%o4
+___sxx:	
+	call	___syy
+	nop
+___syy:
+	sethi   %hi(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
+	or      %o5,%lo(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
+	add	%o7,%o5,%o5
+	/* restore return address */
+	mov	%o4,%o7
+	mov	%o5,%o4
+	/* o4 has the GOT pointer */
+#endif
+	sethi	%hi(SYMBOL_NAME(____sig_table)),%o5
+	or	%o5,%lo(SYMBOL_NAME(____sig_table)),%o5
+#ifdef __PIC__
+	add	%o5,%o4,%o4
+	ld	[%o4],%o5
+#endif
+	sll	%o0,2,%o4
+	add	%o5,%o4,%o4
+	ld	[%o4],%o4
+	ld	[%fp + REGWIN_SZ + 4],%o1         /* Load subcode */
+	ld      [%fp + REGWIN_SZ + 8],%o2         /* pointer to sigcontext */
+	call	%o4
+	ld      [%fp + REGWIN_SZ + 12],%o3        /* Address where signal ocurred */
+
+	/* handler returned, restore state */
+	tst	%l0
+	be	1f
+	wr	%l1,%g0,%y
+	
+	/* fpu restoration */
+	ld      [%sp + CCFSZ + 0], %fsr
+        ldd     [%sp + CCFSZ + 8], %f0
+        ldd     [%sp + CCFSZ + 16], %f2
+        ldd     [%sp + CCFSZ + 24], %f4
+        ldd     [%sp + CCFSZ + 32], %f6
+        ldd     [%sp + CCFSZ + 40], %f8
+        ldd     [%sp + CCFSZ + 48], %f10
+        ldd     [%sp + CCFSZ + 56], %f12
+        ldd     [%sp + CCFSZ + 64], %f14
+        ldd     [%sp + CCFSZ + 72], %f16
+        ldd     [%sp + CCFSZ + 80], %f18
+        ldd     [%sp + CCFSZ + 88], %f20
+        ldd     [%sp + CCFSZ + 96], %f22
+        ldd     [%sp + CCFSZ + 104], %f24
+        ldd     [%sp + CCFSZ + 112], %f26
+        ldd     [%sp + CCFSZ + 120], %f28
+        ldd     [%sp + CCFSZ + 128], %f30
+
+1:	
+	mov	%l2,%g2
+	mov	%l3,%g3
+	mov	%l4,%g4
+	mov	%l5,%g5
+	mov	%l6,%g6
+	mov	%l7,%g7
+	
+	/* call sigreturn */
+	restore	%g0,SYS_sigreturn,%g1 	 /* register back and set syscall */
+	add	%sp,64+16,%o0
+	t	0x10
+	/* if we return, sysreturn failed */
+	mov	SYS_exit,%g1
+	t	0x10
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/__brk.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/__brk.c
@@ -0,0 +1,30 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+extern void * ___brk_addr;
+
+extern int __init_brk ();
+
+int __brk(void * end_data_seg)
+{
+    if (__init_brk () == 0)
+    {
+	__asm__ volatile ("mov %1, %%g1\n\t"
+			  "mov %2, %%o0\n\t"
+			  "t 0x10\n\t"
+			  "mov %%o0, %0\n\t"
+		:"=r" (___brk_addr)
+		:"0" (SYS_brk),"r" (end_data_seg)
+	        :"g1", "o0");
+	if (___brk_addr == end_data_seg)
+		return 0;
+	errno = ENOMEM;
+    }
+    return -1;
+}
+
+#include <gnu-stabs.h>
+#ifdef weak_alias
+weak_alias (__brk, brk);
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/__fork.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/__fork.S
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* New changes: changed from SYSCALL__ to SYSCALL, we did not have the */
+/* fork */
+
+#include <sysdep.h>
+
+SYSCALL__ (fork, 0)
+	tst %o1
+	be,a parent
+	nop
+	/* child: return 0 */
+	clr %o0
+parent:
+	ret
+
+#ifdef __ELF__
+.globl __vfork; __vfork=__fork
+
+.globl vfork; vfork=__fork
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/__init_brk.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/__init_brk.c
@@ -0,0 +1,25 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+void * ___brk_addr = 0;
+
+int
+__init_brk ()
+{
+    if (___brk_addr == 0)
+    {
+	__asm__ volatile ("or %%g0, %%g0, %%o0\n\t"
+			  "mov %1, %%g1\n\t"
+			  "t 0x10\n\t"
+			  "mov %%o0, %0\n\t"
+		:"=r" (___brk_addr)
+		:"0" (SYS_brk) : "g1", "o0");
+	if (___brk_addr == 0)
+	{
+	  errno = ENOMEM;
+	  return -1;
+	}
+    }
+    return 0;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/__pipe.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/__pipe.S
@@ -0,0 +1,28 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <sysdep.h>
+
+ENTRY (__libc_pipe)
+	mov %o0, %o2		/* Save PIPEDES. */
+PSEUDO_NOENT(__libc_pipe, pipe, 1)
+	st %o0, [%o2]		/* PIPEDES[0] = %o0; */
+	st %o1, [%o2 + 4]	/* PIPEDES[1] = %o1; */
+	retl			/* return 0; */
+	clr %o0
+SYSCALL__POST(pipe,1)
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/__sbrk.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/__sbrk.c
@@ -0,0 +1,33 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+extern void * ___brk_addr;
+
+extern int __init_brk (void);
+
+void *
+__sbrk(ptrdiff_t increment)
+{
+    if (__init_brk () == 0)
+    {
+	void * tmp = ___brk_addr+increment;
+	__asm__ volatile ("or %%g0, %1, %%g1\n\t"
+			  "or %%g0, %2, %%o0\n\t"
+			  "t 0x10\n\t"
+			  "mov %%o0, %0\n\t"
+		:"=r" (___brk_addr)
+		:"0" (SYS_brk),"r" (tmp) : "g1", "o0");
+	if (___brk_addr == tmp)
+		return tmp-increment;
+	errno = ENOMEM;
+	return ((void *) -1);
+    }
+    return ((void *) -1);
+}
+
+
+#include <gnu-stabs.h>
+#ifdef weak_alias
+weak_alias (__sbrk, sbrk);
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/__select.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/__select.S
@@ -0,0 +1,22 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <sysdep.h>
+
+SYSCALL__ (select, 4)
+	ret
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/__sigact.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/__sigact.c
@@ -0,0 +1,103 @@
+/* Signal handling code for Linux/SPARC */
+/* Miguel de Icaza -- miguel@nuclecu.unam.mx */
+
+#include <syscall.h>
+#include <sys/signal.h>
+#include <errno.h>
+
+extern void ____sparc_signal_trampoline (int);
+long ____sig_table [NSIG];
+
+int
+__trampoline_sigaction(int sig,struct sigaction * new, struct sigaction * old)
+{
+	int ret;
+	int need_to_hide_trick = 0;
+	__sighandler_t old_sh;
+	
+	if (new){
+		if (new->sa_handler != SIG_DFL && new->sa_handler != SIG_IGN){
+		        old_sh = ____sig_table [sig];
+			____sig_table [sig] = (long) new->sa_handler;
+			new->sa_handler = ____sparc_signal_trampoline;
+			need_to_hide_trick = 1;
+		}
+	}
+	__asm__("or %%g0,%0,%%g1\n\t"
+		"or %%g0,%1,%%o0\n\t"
+		"or %%g0,%2,%%o1\n\t"
+		"or %%g0,%3,%%o2\n\t"
+		"t  0x10\n\t"
+		"bcc 1f\n\t"
+		"or %%o0, %%g0, %0\n\t"
+		"sub %%g0, %%o0, %0\n\t"
+		"1:"
+		: "=r" (ret), "=r" ((long)sig), "=r" ((long) new), "=r" ((long)old)
+		: "0" (SYS_sigaction), "1" (sig), "2" (new), "3" (old)
+		: "g1", "o0", "o1", "o2");
+		 
+	if (ret >= 0){
+   	        if (old && old->sa_handler == ____sparc_signal_trampoline){
+		        if (need_to_hide_trick)
+			    old->sa_handler = old_sh;
+			else
+			    old->sa_handler = ____sig_table [sig];
+		}
+		if (need_to_hide_trick)
+		        new->sa_handler = ____sig_table [sig];
+		return 0;
+	}
+	errno = -ret;
+	return -1;
+}
+
+int
+__new_sigaction (int sig, struct sigaction *new, struct sigaction *old)
+{
+	int ret;
+
+	sig = -sig;
+	
+	__asm__("or %%g0,%0,%%g1\n\t"
+		"or %%g0,%1,%%o0\n\t"
+		"or %%g0,%2,%%o1\n\t"
+		"or %%g0,%3,%%o2\n\t"
+		"t  0x10\n\t"
+		"bcc 1f\n\t"
+		"or %%o0, %%g0, %0\n\t"
+		"sub %%g0,%%o0,%0\n\t"
+		"1:"
+		: "=r" (ret), "=r" ((long)sig), "=r" ((long) new), "=r" ((long)old)
+		: "0" (SYS_sigaction), "1" (sig), "2" (new), "3" (old)
+		: "g1", "o0", "o1", "o2");
+	if (ret >= 0)
+		return 0;
+	errno = -ret;
+	return -1;
+}
+
+int
+__sigaction (int sig, struct sigaction *new, struct sigaction *old)
+{
+	static (*sigact_routine)(int, struct sigaction *, struct sigaction *);
+	int ret;
+	
+	if (sigact_routine)
+		return (*sigact_routine)(sig, new, old);
+
+	{
+	    struct sigaction sa;
+	    
+	    ret = __new_sigaction (1, NULL, &sa);
+	    if (ret == -1)
+		sigact_routine = __trampoline_sigaction;
+	    else
+		sigact_routine = __new_sigaction;
+	} 
+	return __sigaction (sig, new, old);
+}
+
+#include <gnu-stabs.h>
+#ifdef weak_alias
+weak_alias (__sigaction, sigaction);
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/_errlist.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/_errlist.c
@@ -0,0 +1,146 @@
+#include <ansidecl.h>
+#include <stddef.h>
+#if 0
+#include <errno.h>
+#endif
+
+CONST char *CONST _sys_errlist[] = {
+        "Unknown error",                        /* 0 */
+	"Operation not permitted", 		/* EPERM */
+	"No such file or directory", 		/* ENOENT */
+	"No such process", 			/* ESRCH */
+	"Interrupted system call", 		/* EINTR */
+	"I/O error", 				/* EIO */
+	"No such device or address", 		/* ENXIO */
+	"Arg list too long", 			/* E2BIG */
+	"Exec format error", 			/* ENOEXEC */
+	"Bad file number", 			/* EBADF */
+	"No child processes", 			/* ECHILD */
+	"Try again", 				/* EAGAIN */
+	"Out of memory", 			/* ENOMEM */
+	"Permission denied", 			/* EACCES */
+	"Bad address", 				/* EFAULT */
+	"Block device required", 		/* ENOTBLK */
+	"Device or resource busy", 		/* EBUSY */
+	"File exists", 				/* EEXIST */
+	"Cross-device link", 			/* EXDEV */
+	"No such device", 			/* ENODEV */
+	"Not a directory", 			/* ENOTDIR */
+	"Is a directory", 			/* EISDIR */
+	"Invalid argument", 			/* EINVAL */
+	"File table overflow", 			/* ENFILE */
+	"Too many open files", 			/* EMFILE */
+	"Not a typewriter", 			/* ENOTTY */
+	"Text file busy", 			/* ETXTBSY */
+	"File too large", 			/* EFBIG */
+	"No space left on device", 		/* ENOSPC */
+	"Illegal seek", 			/* ESPIPE */
+	"Read-only file system", 		/* EROFS */
+	"Too many links", 			/* EMLINK */
+	"Broken pipe", 				/* EPIPE */
+	"Math argument out of domain of func", 	/* EDOM */
+	"Math result not representable", 	/* ERANGE */
+	"Operation would block", 		/* EWOULDBLOCK */
+	"Operation now in progress", 		/* EINPROGRESS */
+	"Operation already in progress", 	/* EALREADY */
+	"Socket operation on non-socket", 	/* ENOTSOCK */
+	"Destination address required", 	/* EDESTADDRREQ */
+	"Message too long", 			/* EMSGSIZE */
+	"Protocol wrong type for socket", 	/* EPROTOTYPE */
+	"Protocol not available", 		/* ENOPROTOOPT */
+	"Protocol not supported", 		/* EPROTONOSUPPORT */
+	"Socket type not supported", 		/* ESOCKTNOSUPPORT */
+	"Operation not supported on transport endpoint", 	/* EOPNOTSUPP */
+	"Protocol family not supported", 	/* EPFNOSUPPORT */
+	"Address family not supported by protocol", 	/* EAFNOSUPPORT */
+	"Address already in use", 		/* EADDRINUSE */
+	"Cannot assign requested address", 	/* EADDRNOTAVAIL */
+	"Network is down", 			/* ENETDOWN */
+	"Network is unreachable", 		/* ENETUNREACH */
+	"Network dropped connection because of reset", 	/* ENETRESET */
+	"Software caused connection abort", 	/* ECONNABORTED */
+	"Connection reset by peer", 		/* ECONNRESET */
+	"No buffer space available", 		/* ENOBUFS */
+	"Transport endpoint is already connected", 	/* EISCONN */
+	"Transport endpoint is not connected", 	/* ENOTCONN */
+	"Cannot send after transport endpoint shutdown", 	/* ESHUTDOWN */
+	"Too many references: cannot splice", 	/* ETOOMANYREFS */
+	"Connection timed out", 		/* ETIMEDOUT */
+	"Connection refused", 			/* ECONNREFUSED */
+	"Too many symbolic links encountered", 	/* ELOOP */
+	"File name too long", 			/* ENAMETOOLONG */
+	"Host is down", 			/* EHOSTDOWN */
+	"No route to host", 			/* EHOSTUNREACH */
+	"Directory not empty", 			/* ENOTEMPTY */
+        "Too many processes",                   /* EPROCLIM: SunOS */
+	"Too many users", 			/* EUSERS */
+        "Quota exceeded",                       /* EDQUOT */
+	"Stale NFS file handle", 		/* ESTALE */
+	"Object is remote", 			/* EREMOTE */
+	"Device not a stream", 			/* ENOSTR */
+	"Timer expired", 			/* ETIME */
+	"Out of streams resources", 		/* ENOSR */
+	"No message of desired type", 		/* ENOMSG */
+	"Not a data message", 			/* EBADMSG */
+	"Identifier removed", 			/* EIDRM */
+	"Resource deadlock would occur", 	/* EDEADLK */
+	"No record locks available", 		/* ENOLCK */
+/* RFS */
+	"Machine is not on the network", 	/* ENONET */
+        "Object is remote",                     /* SunOS only: ERREMOTE */
+	"Link has been severed", 		/* ENOLINK */
+	"Advertise error", 			/* EADV */
+	"Srmount error", 			/* ESRMNT */
+	"Communication error on send", 		/* ECOMM */
+	"Protocol error", 			/* EPROTO */
+	"Multihop attempted", 			/* EMULTIHOP */
+	"RFS specific error", 			/* EDOTDOT */
+	"Remote address changed", 		/* EREMCHG */
+	"Function not implemented", 		/* ENOSYS */
+	"Streams pipe error", 			/* ESTRPIPE */
+	"Value too large for defined data type", 	/* EOVERFLOW */
+	"File descriptor in bad state", 	/* EBADFD */
+	"Channel number out of range", 		/* ECHRNG */
+	"Level 2 not synchronized", 		/* EL2NSYNC */
+	"Level 3 halted", 			/* EL3HLT */
+	"Level 3 reset", 			/* EL3RST */
+     	"Link number out of range", 		/* ELNRNG */
+	"Protocol driver not attached", 	/* EUNATCH */
+	"No CSI structure available", 		/* ENOCSI */
+	"Level 2 halted", 			/* EL2HLT */
+	"Invalid exchange", 			/* EBADE */
+	"Invalid request descriptor", 		/* EBADR */
+	"Exchange full", 			/* EXFULL */
+	"No anode", 				/* ENOANO */
+	"Invalid request code", 		/* EBADRQC */
+	"Invalid slot", 			/* EBADSLT */
+	"File locking deadlock error", 		/* EDEADLOCK */
+	"Bad font file format", 		/* EBFONT */
+	"Cannot exec a shared library directly", 	/* ELIBEXEC */
+	"No data available", 			/* ENODATA */
+	"Accessing a corrupted shared library", 	/* ELIBBAD */
+	"Package not installed", 		/* ENOPKG */
+	"Can not access a needed shared library", 	/* ELIBACC */
+	"Name not unique on network", 		/* ENOTUNIQ */
+	"Interrupted system call should be restarted", 	/* ERESTART */
+	"Structure needs cleaning", 		/* EUCLEAN */
+	"Not a XENIX named type file", 		/* ENOTNAM */
+	"No XENIX semaphores available", 	/* ENAVAIL */
+	"Is a named type file", 		/* EISNAM */
+	"Remote I/O error", 			/* EREMOTEIO */
+	"Illegal byte sequence", 		/* EILSEQ */
+	"Attempting to link in too many shared libraries", 	/* ELIBMAX */
+	".lib section in a.out corrupted", 	/* ELIBSCN */
+	NULL
+};
+
+
+#define NR_ERRORS ((sizeof (_sys_errlist))/(sizeof(char *))-1)
+
+CONST int _sys_nerr = NR_ERRORS;
+
+#include <gnu-stabs.h>
+#ifdef weak_alias
+weak_alias (_sys_errlist, sys_errlist);
+weak_alias (_sys_nerr, sys_nerr);
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/Makefile
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/Makefile
@@ -0,0 +1,72 @@
+#
+# Makefile for crt0.o of Linux
+#
+#
+
+LD=true
+MV=true
+override STATIC_SHARED=false
+override SHARED=false
+override DEBUG=false
+
+TOPDIR=../../../..
+
+include $(TOPDIR)/Makeconfig
+include $(TOPDIR)/Makerules
+
+RFLAGS= -DDEFAULT_LOCALE="`$(CC) -E defaultlocale.c | grep DEFAULT_LOCALE | cut -f2 -d':'`"
+PIC_CFLAGS=$(CFLAGS)
+SHARED_CFLAGS=$(CFLAGS)
+DEBUG_CFLAGS=$(CFLAGS)
+
+PROFILE_CFLAGS=$(CFLAGS)
+CHECKER_CFLAGS=$(CFLAGS)
+CC = $(REALCC)
+
+SRCS= defaultlocale.c
+
+ifeq ($(ELF),true)
+
+lib:: $(ELF_SHARED_DIR)/crt1.o \
+	$(ELF_SHARED_DIR)/crti.o $(ELF_SHARED_DIR)/crtn.o \
+	$(ELF_PROFILE_DIR)/gcrt1.o
+
+$(ELF_SHARED_DIR)/crt1.o: crt1.s crt0.s
+	as crt1.s -o $(ELF_SHARED_DIR)/crt1.o
+	as crt0.s -o $(ELF_SHARED_DIR)/crt0.o
+
+$(ELF_PROFILE_DIR)/gcrt1.o: gcrt1.s gcrt0.s
+	as gcrt1.s -o $(ELF_PROFILE_DIR)/gcrt1.o
+	as gcrt0.s -o $(ELF_PROFILE_DIR)/gcrt0.o
+else
+
+ifeq ($(CHECKER),true)
+lib:: $(CHECKER_DIR)/chkrcrt0.o
+endif
+
+ifeq ($(PROFILE),true)
+lib:: $(PROFILE_DIR)/gcrt0.o
+endif
+
+ifeq ($(STATIC),true)
+lib:: $(STATIC_DIR)/crt0.o
+endif
+
+endif
+
+lib::
+	@true
+
+realclean clean:
+	$(RM) -f core *.s *.o *.a tmp_make foo
+
+depend:
+	$(CC) -M $(SRCS) | \
+		sed -e 's,^[    ]*\(.*\.o\)[    ]*:,$(STATIC_DIR)/crt0.o $(PROFILE_DIR)/gcrt0.o $(ELF_SHARED_DIR)/crt1.o $(ELF_PROFILE_DIR)/gcrt1.o $(CHECKER_DIR)/checkcrt0.o:,' > .depend
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/chkrcrt0.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/chkrcrt0.S
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1993 Eric Youngdale, Peter MacDonald, David Engel
+ * and Hongjiu Lu.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. The name of the above contributors may not be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Notice of general intent:
+ *
+ * The linux operating system generally contains large amounts of code
+ * that fall under the GNU General Public License, or GPL for short.
+ * This file contains source code that by it's very nature would always
+ * be linked with an application program, and because of this a GPL type
+ * of copyright on this file would place restrictions upon the
+ * distribution of binary-only commercial software.  Since the goal of the
+ * Linux project as a whole is not to discourage the development and
+ * distribution of commercial software for Linux, this file has been placed
+ * under a more relaxed BSD-style of copyright.
+ *
+ * It is the general understanding of the above contributors that a
+ * program executable linked to a library containing code that falls
+ * under the GPL or GLPL style of license is not subject to the terms of
+ * the GPL or GLPL license if the program executable(s) that are supplied
+ * are linked to a shared library form of the GPL or GLPL library, and as long
+ * as the form of the shared library is such that it is possible for
+ * the end user to modify and rebuild the library and use it in
+ * conjunction with the program executable.
+ */
+/* Changes by Tristan Gingold 
+   * does not handle the shared libraries
+   * call __chkr_init_chkr before main
+ */
+
+	.file "chkrcrt0.S"
+	.stabs "/libc-linux/sysdeps/linux/i386/crt/",100,0,0,__entry
+	.stabs "chkrcrt0.S",100,0,0,__entry
+	.text
+	.globl	___crt_dummy__
+___crt_dummy__:
+__entry:
+/*
+ *	This is important, and was missing from the new version...
+ */
+	movl $45,%eax
+	movl $0,%ebx
+	int  $0x80
+	movl %eax,____brk_addr
+
+/*
+ *	just set the __chkr_maccess flag
+ */
+	movl %eax,___chkr_maccess
+
+/*
+ *	ok, set up the 387 flags and ___environ.
+ */	
+	fldcw init_cw
+	movl 8(%esp),%eax
+	movl %eax,___environ
+/*
+ * The next thing we do is initialize Checker.
+ * Because 387 flags are set, Checker can use the FPU.
+ */
+	call ___chkr_init_chkr
+/*
+ * Now we can call __setfpucw and _main
+ */
+	movzwl ___fpu_control,%eax
+	call chkr_0_5_2_4_chkr		/* for the pushl */
+	pushl %eax
+	call ___setfpucw
+	addl $4,%esp
+/* Some functions may be needed. */
+	call ___libc_init
+	call chkr_0_5_0_4_chkr		/* for the call */
+	call _main
+	call chkr_0_5_2_4_chkr		/* for pushl */
+	pushl %eax
+	call _exit
+/*
+ *	Just in case _exit fails... We use int $0x80 for __exit().
+ */
+	popl %ebx
+done:
+	movl $1,%eax
+	int $0x80
+	jmp done
+
+	.stabd 68,0,1
+	.stabs "__entry:F39",36,0,1,__entry
+
+#ifdef __i486__
+	.align  4,0x90
+#else
+	.align  2,0x90
+#endif
+init_cw:
+	.word 0x1372
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/crt0.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/crt0.c
@@ -0,0 +1,184 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define NO_SHLIB
+#ifndef NO_SHLIB
+#include <a.out.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <link.h>
+#include <syscall.h>
+#endif
+
+#if !defined (__GNUC__) || __GNUC__ < 2
+  #error This file uses GNU C extensions; you must compile with GCC version 2.
+#endif
+
+/* The first piece of initialized data.  */
+int __data_start = 0;
+
+#define HAVE_GNU_LD
+#ifndef	HAVE_GNU_LD
+#undef	environ
+#define	__environ	environ
+#endif
+
+extern void *___brk_addr;
+extern char **__environ;
+
+extern void EXFUN(__libc_init, (int argc, char **argv, char **envp));
+extern int EXFUN(main, (int argc, char **argv, char **envp));
+
+register long int sp asm("%sp"), fp asm("%fp");
+
+#ifndef NO_SHLIB
+static void EXFUN(init_shlib, (NOARGS));
+#endif
+
+#ifndef NO_EXPLICIT_START
+/* Declare _start with an explicit assembly symbol name of `start'
+   (note no leading underscore).  This is the name Sun's crt0.o uses,
+   and programs are often linked with `ld -e start'.  */
+/* void _start (void) asm ("start"); */
+#endif
+
+void
+_start (void)
+{
+  /* It is important that these be declared `register'.
+     Otherwise, when compiled without optimization, they are put on the
+     stack, which loses completely after we zero the FP.  */
+  register int argc;
+  register char **argv, **envp;
+  
+  /* Unwind the frame built when we entered the function.  */
+  asm("restore");
+
+  /* And clear the frame pointer.  */
+  fp = 0;
+
+  /* The argument info starts after one register
+     window (64 bytes) past the SP.  */
+  argc = ((int *) sp)[16];
+  argv = (char **) &((int *) sp)[17];
+  envp = &argv[argc + 1];
+  __environ = envp;
+
+  /* Allocate 24 bytes of stack space for the register save area.  */
+  sp -= 24;
+  __libc_init (argc, argv, envp);
+#ifdef ELF_INIT_FINI
+  {
+      extern void _fini (void);
+      atexit (_fini);
+      _init ();
+  }
+#endif
+  exit (main (argc, argv, envp));
+}
+
+#ifndef NO_SHLIB
+#ifndef __ELF__
+
+/* System calls for use by the bootstrap routine.
+   These are defined here since the usual calls may be dynamically linked.  */
+
+int syscall (int sysno, ...) asm ("init_syscall");
+asm ("init_syscall:\n"
+     "	clr %g1\n"
+     "	ta 0x10\n"
+     "	bcc 1f\n"
+     "	sethi %hi(_errno), %g1\n"
+     "	st %o0, [%g1 + %lo(_errno)]\n"
+     "	sub %g0, 1, %o0\n"
+     "1:retl\n"
+     "	nop");
+
+static void
+DEFUN_VOID(init_shlib)
+{
+  extern Elf32_Dyn _DYNAMIC [];
+  int so, zf;
+  caddr_t somap;
+  caddr_t sodmap;
+  caddr_t sobssmap;
+  void (*ldstart) (int, int);
+  struct exec soexec;
+  struct 
+    {
+      caddr_t crt_ba;
+      int crt_dzfd;
+      int crt_ldfd;
+      struct link_dynamic *crt_dp;
+      char **crt_ep;
+      caddr_t crt_bp;
+    } soarg;
+  
+  /* If not dynamically linked, do nothing.  */
+  if (&_DYNAMIC == 0)
+    return;
+
+  /* Map in the dynamic linker.  */
+  so = syscall (SYS_open, "/usr/lib/ld.so", O_RDONLY);
+  if (syscall (SYS_read, so, &soexec, sizeof (soexec)) != sizeof (soexec)
+      || soexec.a_magic != ZMAGIC)
+    {
+      static CONST char emsg[] = "crt0: no /usr/lib/ld.so\n";
+      
+      syscall (SYS_write, 2, emsg, sizeof (emsg) - 1);
+      syscall (SYS_exit, 127);
+    }
+  somap = (caddr_t) syscall (SYS_mmap, 0,
+			     soexec.a_text + soexec.a_data + soexec.a_bss,
+			     PROT_READ | PROT_EXEC, _MAP_NEW | MAP_PRIVATE,
+			     so, 0);
+  sodmap = (caddr_t) syscall (SYS_mmap, somap + soexec.a_text, soexec.a_data,
+			      PROT_READ | PROT_WRITE | PROT_EXEC,
+			      _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
+			      so, soexec.a_text);
+  zf = syscall (SYS_open, "/dev/zero", O_RDONLY);
+  if (soexec.a_bss != 0)
+    sobssmap = (caddr_t) syscall (SYS_mmap,
+				  somap + soexec.a_text + soexec.a_data,
+				  soexec.a_bss,
+				  PROT_READ | PROT_WRITE | PROT_EXEC,
+				  _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
+				  zf, 0);
+
+  /* Call the entry point of the dynamic linker.  */
+  soarg.crt_ba = somap;
+  soarg.crt_dzfd = zf;
+  soarg.crt_ldfd = so;
+  soarg.crt_dp = &_DYNAMIC;
+  soarg.crt_ep = __environ;
+  soarg.crt_bp = (caddr_t) &&retaddr;
+  
+  ldstart = (__typeof (ldstart)) (somap + soexec.a_entry);
+  (*ldstart) (1, (char *) &soarg - (char *) sp);
+
+ retaddr:
+}
+#endif
+#endif
+
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/crt1.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/crt1.c
@@ -0,0 +1,2 @@
+#define ELF_INIT_FINI
+#include "crt0.c"
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/crti.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/crti.S
@@ -0,0 +1,13 @@
+#define ALIGN_DATA	.align	4
+
+	.section ".init"
+	.globl _init
+        .type _init,function
+_init:
+        save %sp,-112,%sp
+
+	.section ".fini"
+	.globl _fini
+        .type _fini,function
+_fini:
+        save %sp,-112,%sp
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/crtn.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/crtn.S
@@ -0,0 +1,9 @@
+#ifdef __sparc
+	.section ".init"
+	ret
+	restore
+
+	.section ".fini"
+	ret
+	restore
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/defaultlocale.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/defaultlocale.c
@@ -0,0 +1,3 @@
+#include <locale.h>
+
+DEFAULT_LOCALE:LC_ALL
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/gcrt0.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/gcrt0.c
@@ -0,0 +1,191 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define NO_SHLIB
+#ifndef NO_SHLIB
+#include <sys/exec.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <link.h>
+#include <syscall.h>
+#endif
+
+#if !defined (__GNUC__) || __GNUC__ < 2
+  #error This file uses GNU C extensions; you must compile with GCC version 2.
+#endif
+
+/* The first piece of initialized data.  */
+int __data_start = 0;
+
+#define HAVE_GNU_LD
+#ifndef	HAVE_GNU_LD
+#undef	environ
+#define	__environ	environ
+#endif
+
+extern void *___brk_addr;
+extern char **__environ;
+
+extern void EXFUN(__libc_init, (int argc, char **argv, char **envp));
+extern int EXFUN(main, (int argc, char **argv, char **envp));
+
+register long int sp asm("%sp"), fp asm("%fp");
+
+#ifndef NO_SHLIB
+static void EXFUN(init_shlib, (NOARGS));
+#endif
+
+#undef NO_EXPLICIT_START
+#ifndef NO_EXPLICIT_START
+/* Declare _start with an explicit assembly symbol name of `start'
+   (note no leading underscore).  This is the name Sun's crt0.o uses,
+   and programs are often linked with `ld -e start'.  */
+/* void _start (void) asm ("start"); */
+#endif
+
+extern int _etext (int);
+extern void _mcleanup (void);
+void
+_start (void)
+{
+  /* It is important that these be declared `register'.
+     Otherwise, when compiled without optimization, they are put on the
+     stack, which loses completely after we zero the FP.  */
+  register int argc;
+  register char **argv, **envp;
+  
+  /* Unwind the frame built when we entered the function.  */
+  asm("restore");
+
+  /* And clear the frame pointer.  */
+  fp = 0;
+
+  /* The argument info starts after one register
+     window (64 bytes) past the SP.  */
+  argc = ((int *) sp)[16];
+  argv = (char **) &((int *) sp)[17];
+  envp = &argv[argc + 1];
+  __environ = envp;
+
+   atexit (_mcleanup);
+   monstartup(_etext, _start);
+#ifndef NO_SHLIB
+  init_shlib ();
+#endif
+
+  /* Allocate 24 bytes of stack space for the register save area.  */
+  sp -= 24;
+  __libc_init (argc, argv, envp);
+#ifdef ELF_INIT_FINI
+  {
+      extern void _fini (void);
+      atexit (_fini);
+      _init ();
+  }
+#endif
+  exit (main (argc, argv, envp));
+}
+
+#ifndef NO_SHLIB
+#ifndef __ELF__
+/* System calls for use by the bootstrap routine.
+   These are defined here since the usual calls may be dynamically linked.  */
+
+int syscall (int sysno, ...) asm ("init_syscall");
+asm ("init_syscall:\n"
+     "	clr %g1\n"
+     "	ta 0x10\n"
+     "	bcc 1f\n"
+     "	sethi %hi(_errno), %g1\n"
+     "	st %o0, [%g1 + %lo(_errno)]\n"
+     "	sub %g0, 1, %o0\n"
+     "1:retl\n"
+     "	nop");
+
+static void
+DEFUN_VOID(init_shlib)
+{
+  extern struct link_dynamic _DYNAMIC;
+  int so, zf;
+  caddr_t somap;
+  caddr_t sodmap;
+  caddr_t sobssmap;
+  void (*ldstart) (int, int);
+  struct exec soexec;
+  struct 
+    {
+      caddr_t crt_ba;
+      int crt_dzfd;
+      int crt_ldfd;
+      struct link_dynamic *crt_dp;
+      char **crt_ep;
+      caddr_t crt_bp;
+    } soarg;
+  
+  /* If not dynamically linked, do nothing.  */
+  if (&_DYNAMIC == 0)
+    return;
+
+  /* Map in the dynamic linker.  */
+  so = syscall (SYS_open, "/usr/lib/ld.so", O_RDONLY);
+  if (syscall (SYS_read, so, &soexec, sizeof (soexec)) != sizeof (soexec)
+      || soexec.a_magic != ZMAGIC)
+    {
+      static CONST char emsg[] = "crt0: no /usr/lib/ld.so\n";
+      
+      syscall (SYS_write, 2, emsg, sizeof (emsg) - 1);
+      syscall (SYS_exit, 127);
+    }
+  somap = (caddr_t) syscall (SYS_mmap, 0,
+			     soexec.a_text + soexec.a_data + soexec.a_bss,
+			     PROT_READ | PROT_EXEC, _MAP_NEW | MAP_PRIVATE,
+			     so, 0);
+  sodmap = (caddr_t) syscall (SYS_mmap, somap + soexec.a_text, soexec.a_data,
+			      PROT_READ | PROT_WRITE | PROT_EXEC,
+			      _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
+			      so, soexec.a_text);
+  zf = syscall (SYS_open, "/dev/zero", O_RDONLY);
+  if (soexec.a_bss != 0)
+    sobssmap = (caddr_t) syscall (SYS_mmap,
+				  somap + soexec.a_text + soexec.a_data,
+				  soexec.a_bss,
+				  PROT_READ | PROT_WRITE | PROT_EXEC,
+				  _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
+				  zf, 0);
+
+  /* Call the entry point of the dynamic linker.  */
+  soarg.crt_ba = somap;
+  soarg.crt_dzfd = zf;
+  soarg.crt_ldfd = so;
+  soarg.crt_dp = &_DYNAMIC;
+  soarg.crt_ep = __environ;
+  soarg.crt_bp = (caddr_t) &&retaddr;
+  
+  ldstart = (__typeof (ldstart)) (somap + soexec.a_entry);
+  (*ldstart) (1, (char *) &soarg - (char *) sp);
+
+ retaddr:
+}
+#endif
+#endif
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/gcrt1.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/gcrt1.c
@@ -0,0 +1,2 @@
+#define ELF_INIT_FINI
+#include "gcrt0.c"
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/gcrtn.S
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/gcrtn.S
@@ -0,0 +1,20 @@
+# This file contains stuff that goes at the end of the .init and .fini
+# sections.  The idea is that the linker simply strings together the init
+# sections from the various input files, and this end up at the end.
+
+
+	.section .init
+/*
+ *	Setup profiling
+ */
+	pushl $_mcleanup
+	call atexit
+	addl $4,%esp
+	pushl $_etext
+	pushl $_start
+	call monstartup
+	addl $8,%esp
+	ret $0
+
+	.section .fini
+	ret $0
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/crt1.s
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/crt1.s
@@ -0,0 +1,49 @@
+	.file	"crt1.c"
+	.version	"01.01"
+gcc2_compiled.:
+	.global __data_start
+.section	".data"
+	.align 4
+	.type	 __data_start,#object
+	.size	 __data_start,4
+__data_start:
+	.word	0
+.section	".text"
+	.align 4
+	.global _start
+	.type	 _start,#function
+	.proc	020
+_start:
+	!#PROLOGUE# 0
+	save %sp,-104,%sp
+	!#PROLOGUE# 1
+	restore
+	mov 0,%fp
+	ld [%sp+64],%l1
+	add %sp,68,%l2
+	sll %l1,2,%l0
+	add %l0,4,%l0
+	add %l2,%l0,%l0
+	sethi %hi(__environ),%o0
+	st %l0,[%o0+%lo(__environ)]
+	add %sp,-24,%sp
+	mov %l1,%o0
+	mov %l2,%o1
+	call __libc_init,0
+	mov %l0,%o2
+	sethi %hi(_fini),%o0
+	call atexit,0
+	or %o0,%lo(_fini),%o0
+	call _init,0
+	nop
+	mov %l1,%o0
+	mov %l2,%o1
+	call main,0
+	mov %l0,%o2
+	call exit,0
+	nop
+	ret
+	restore
+.LLfe1:
+	.size	 _start,.LLfe1-_start
+	.ident	"GCC: (GNU) 2.7.2.3"
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/crt0.s
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/crt0.s
@@ -0,0 +1,44 @@
+	.file	"crt0.c"
+	.version	"01.01"
+gcc2_compiled.:
+	.global __data_start
+.section	".data"
+	.align 4
+	.type	 __data_start,#object
+	.size	 __data_start,4
+__data_start:
+	.word	0
+.section	".text"
+	.align 4
+	.global _start
+	.type	 _start,#function
+	.proc	020
+_start:
+	!#PROLOGUE# 0
+	save %sp,-104,%sp
+	!#PROLOGUE# 1
+	restore
+	mov 0,%fp
+	ld [%sp+64],%l1
+	add %sp,68,%l2
+	sll %l1,2,%l0
+	add %l0,4,%l0
+	add %l2,%l0,%l0
+	sethi %hi(__environ),%o0
+	st %l0,[%o0+%lo(__environ)]
+	add %sp,-24,%sp
+	mov %l1,%o0
+	mov %l2,%o1
+	call __libc_init,0
+	mov %l0,%o2
+	mov %l1,%o0
+	mov %l2,%o1
+	call main,0
+	mov %l0,%o2
+	call exit,0
+	nop
+	ret
+	restore
+.LLfe1:
+	.size	 _start,.LLfe1-_start
+	.ident	"GCC: (GNU) 2.7.2.3"
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/gcrt1.s
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/gcrt1.s
@@ -0,0 +1,57 @@
+	.file	"gcrt1.c"
+	.version	"01.01"
+gcc2_compiled.:
+	.global __data_start
+.section	".data"
+	.align 4
+	.type	 __data_start,#object
+	.size	 __data_start,4
+__data_start:
+	.word	0
+.section	".text"
+	.align 4
+	.global _start
+	.type	 _start,#function
+	.proc	020
+_start:
+	!#PROLOGUE# 0
+	save %sp,-104,%sp
+	!#PROLOGUE# 1
+	restore
+	mov 0,%fp
+	ld [%sp+64],%l1
+	add %sp,68,%l2
+	sll %l1,2,%l0
+	add %l0,4,%l0
+	add %l2,%l0,%l0
+	sethi %hi(__environ),%o0
+	st %l0,[%o0+%lo(__environ)]
+	sethi %hi(_mcleanup),%o0
+	call atexit,0
+	or %o0,%lo(_mcleanup),%o0
+	sethi %hi(_etext),%o0
+	or %o0,%lo(_etext),%o0
+	sethi %hi(_start),%o1
+	call monstartup,0
+	or %o1,%lo(_start),%o1
+	add %sp,-24,%sp
+	mov %l1,%o0
+	mov %l2,%o1
+	call __libc_init,0
+	mov %l0,%o2
+	sethi %hi(_fini),%o0
+	call atexit,0
+	or %o0,%lo(_fini),%o0
+	call _init,0
+	nop
+	mov %l1,%o0
+	mov %l2,%o1
+	call main,0
+	mov %l0,%o2
+	call exit,0
+	nop
+	ret
+	restore
+.LLfe1:
+	.size	 _start,.LLfe1-_start
+	.ident	"GCC: (GNU) 2.7.2.3"
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/crt/gcrt0.s
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/crt/gcrt0.s
@@ -0,0 +1,52 @@
+	.file	"gcrt0.c"
+	.version	"01.01"
+gcc2_compiled.:
+	.global __data_start
+.section	".data"
+	.align 4
+	.type	 __data_start,#object
+	.size	 __data_start,4
+__data_start:
+	.word	0
+.section	".text"
+	.align 4
+	.global _start
+	.type	 _start,#function
+	.proc	020
+_start:
+	!#PROLOGUE# 0
+	save %sp,-104,%sp
+	!#PROLOGUE# 1
+	restore
+	mov 0,%fp
+	ld [%sp+64],%l1
+	add %sp,68,%l2
+	sll %l1,2,%l0
+	add %l0,4,%l0
+	add %l2,%l0,%l0
+	sethi %hi(__environ),%o0
+	st %l0,[%o0+%lo(__environ)]
+	sethi %hi(_mcleanup),%o0
+	call atexit,0
+	or %o0,%lo(_mcleanup),%o0
+	sethi %hi(_etext),%o0
+	or %o0,%lo(_etext),%o0
+	sethi %hi(_start),%o1
+	call monstartup,0
+	or %o1,%lo(_start),%o1
+	add %sp,-24,%sp
+	mov %l1,%o0
+	mov %l2,%o1
+	call __libc_init,0
+	mov %l0,%o2
+	mov %l1,%o0
+	mov %l2,%o1
+	call main,0
+	mov %l0,%o2
+	call exit,0
+	nop
+	ret
+	restore
+.LLfe1:
+	.size	 _start,.LLfe1-_start
+	.ident	"GCC: (GNU) 2.7.2.3"
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/getprio.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/getprio.c
@@ -0,0 +1,28 @@
+#include <errno.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+
+#define	PZERO	15
+
+int
+getpriority(int which, int who)
+{
+   long res;
+     
+	__asm__ volatile ("or %%g0, %0, %%g1\n\t"
+			  "or %%g0, %1, %%o0\n\t"
+			  "or %%g0, %2, %%o1\n\t"
+			  "t 0x10\n\t"
+			  "or %%o0, %%g0, %0\n\t"
+			  : "=r" (res), "=r" ((long)which), "=r" ((long)who)
+			  : "0" ((long) SYS_getpriority),
+			    "1" ((long) which), "2" ((long)who)
+			  : "g1", "o0", "o1"
+			  );
+        if (res >= 0) {
+		errno = 0;
+                return (int) PZERO - res;
+        }
+        errno = -res;
+        return -1;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/gmon/Makefile
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/gmon/Makefile
@@ -0,0 +1,29 @@
+#
+# This is Makefile of gmon for Linux
+#
+#
+
+TOPDIR=../../../..
+
+override STATIC=false
+override SHARED=false
+override DEBUG=false
+override CHECKER=false
+
+# That is fake for SUBDIR.
+JUMP_LIB=libgmon
+
+PROFILE_OPT_CFLAGS=-O6
+
+include $(TOPDIR)/Makeconfig
+include $(TOPDIR)/Makerules
+
+PROFILE_LIB=$(PROFILE_DIR)/libgmon.a
+
+DIRS=
+SRCS=gmon.c profil.c
+ASMS= $(SRCS:.c=.s)
+OBJS= $(SRCS:.c=.o)
+ALIASES=
+
+include $(TOPDIR)/Maketargets
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/gmon/README
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/gmon/README
@@ -0,0 +1,31 @@
+Here is a package to use profiling on Linux.
+
+It contains the following files:
+
+-rw-r--r--   1 jrs      user         3410 Jun 14 00:52 profil.patch
+
+patches to Linux v0.96a patchlevel 2 kernel for profiling
+
+-rw-r--r--   1 jrs      user          236 Jun 14 01:21 Makefile
+
+sample makefile for using profiling with an earlier version of GCC.
+
+-rw-r--r--   1 jrs      user         1721 Jun 14 00:45 gcrt0.s
+-rw-r--r--   1 jrs      user          542 Jun 14 01:21 gcrt0.o
+
+source and object of the startup file for programs using -pg profiling
+
+-rw-r--r--   1 jrs      user         9050 Jun 14 00:45 gmon.c
+-rw-r--r--   1 jrs      user         3582 Jun 14 00:45 gmon.h
+-rw-r--r--   1 jrs      user          107 Jun 14 00:45 profil.c
+-rw-r--r--   1 jrs      user         2932 Jun 14 01:21 libgmon.a
+
+profile assist code which belongs in libc.a and libc_p.a
+
+-rw-r--r--   1 jrs      user          965 Jun 14 00:56 gprof.patch
+-rwxr-xr-x   1 jrs      user        78848 Jun 14 01:12 gprof*
+
+small patches and a binary of GNU gprof as found in binutils-1.9.tar.Z
+
+Rick Sladkey
+jrs@world.std.com
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/gmon/gmon.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/gmon/gmon.c
@@ -0,0 +1,339 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)gmon.c	5.3 (Berkeley) 5/22/91";
+#endif /* not lint */
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include "gmon.h"
+
+extern void mcount(); /* asm ("mcount"); */
+/* extern */ char *minbrk; /* asm ("_minbrk"); */
+
+/*
+ *	froms is actually a bunch of unsigned shorts indexing tos
+ */
+static int		profiling = 3;
+static unsigned short	*froms;
+static struct tostruct	*tos = 0;
+static long		tolimit = 0;
+static char		*s_lowpc = 0;
+static char		*s_highpc = 0;
+static unsigned long	s_textsize = 0;
+
+static int	ssiz;
+static char	*sbuf;
+static int	s_scale;
+    /* see profil(2) where this is describe (incorrectly) */
+#define		SCALE_1_TO_1	0x10000L
+
+/*
+ * Control profiling
+ *	profiling is what mcount checks to see if
+ *	all the data structures are ready.
+ */
+void
+moncontrol(mode)
+    int mode;
+{
+    int ret;
+    static int warned = 0;
+
+    if (mode) {
+	/* start */
+	ret = profil(sbuf + sizeof(struct phdr), ssiz - sizeof(struct phdr),
+		(int)s_lowpc, s_scale);
+	if (ret < 0 && errno == ENOSYS && !warned) {
+#   define	PROFIL_WARN	"warning: kernel does not support profiling\n"
+		write(2, PROFIL_WARN, sizeof(PROFIL_WARN));
+		warned = 1;
+	}
+	profiling = 0;
+    } else {
+	/* stop */
+	profil((char *)0, 0, 0, 0);
+	profiling = 3;
+    }
+}
+
+#define	MSG "No space for profiling buffer(s)\n"
+
+void
+monstartup(lowpc, highpc)
+    char	*lowpc;
+    char	*highpc;
+{
+    int			monsize;
+    char		*buffer;
+    register int	o;
+
+	/*
+	 *	round lowpc and highpc to multiples of the density we're using
+	 *	so the rest of the scaling (here and in gprof) stays in ints.
+	 */
+    lowpc = (char *)
+	    ROUNDDOWN((unsigned)lowpc, HISTFRACTION*sizeof(HISTCOUNTER));
+    s_lowpc = lowpc;
+    highpc = (char *)
+	    ROUNDUP((unsigned)highpc, HISTFRACTION*sizeof(HISTCOUNTER));
+    s_highpc = highpc;
+    s_textsize = highpc - lowpc;
+    monsize = (s_textsize / HISTFRACTION) + sizeof(struct phdr);
+    buffer = (char *) sbrk( monsize );
+    if ( buffer == (char *) -1 ) {
+	write( 2 , MSG , sizeof(MSG) );
+	return;
+    }
+    froms = (unsigned short *) sbrk( s_textsize / HASHFRACTION );
+    if ( froms == (unsigned short *) -1 ) {
+	write( 2 , MSG , sizeof(MSG) );
+	froms = 0;
+	return;
+    }
+    tolimit = s_textsize * ARCDENSITY / 100;
+    if ( tolimit < MINARCS ) {
+	tolimit = MINARCS;
+    } else if ( tolimit > 65534 ) {
+	tolimit = 65534;
+    }
+    tos = (struct tostruct *) sbrk( tolimit * sizeof( struct tostruct ) );
+    if ( tos == (struct tostruct *) -1 ) {
+	write( 2 , MSG , sizeof(MSG) );
+	froms = 0;
+	tos = 0;
+	return;
+    }
+    minbrk = (char *) sbrk(0);
+    tos[0].link = 0;
+    sbuf = buffer;
+    ssiz = monsize;
+    ( (struct phdr *) buffer ) -> lpc = lowpc;
+    ( (struct phdr *) buffer ) -> hpc = highpc;
+    ( (struct phdr *) buffer ) -> ncnt = ssiz;
+    monsize -= sizeof(struct phdr);
+    if ( monsize <= 0 )
+	return;
+    o = highpc - lowpc;
+    if( monsize < o )
+#ifndef hp300
+	s_scale = ( (float) monsize / o ) * SCALE_1_TO_1;
+#else /* avoid floating point */
+    {
+	int quot = o / monsize;
+
+	if (quot >= 0x10000)
+		s_scale = 1;
+	else if (quot >= 0x100)
+		s_scale = 0x10000 / quot;
+	else if (o >= 0x800000)
+		s_scale = 0x1000000 / (o / (monsize >> 8));
+	else
+		s_scale = 0x1000000 / ((o << 8) / monsize);
+    }
+#endif
+    else
+	s_scale = SCALE_1_TO_1;
+    moncontrol(1);
+}
+
+void
+_mcleanup()
+{
+    int			fd;
+    int			fromindex;
+    int			endfrom;
+    char		*frompc;
+    int			toindex;
+    struct rawarc	rawarc;
+
+    moncontrol(0);
+    fd = creat( "gmon.out" , 0666 );
+    if ( fd < 0 ) {
+	perror( "mcount: gmon.out" );
+	return;
+    }
+#   ifdef DEBUG
+	fprintf( stderr , "[mcleanup] sbuf 0x%x ssiz %d\n" , sbuf , ssiz );
+#   endif DEBUG
+    write( fd , sbuf , ssiz );
+    endfrom = s_textsize / (HASHFRACTION * sizeof(*froms));
+    for ( fromindex = 0 ; fromindex < endfrom ; fromindex++ ) {
+	if ( froms[fromindex] == 0 ) {
+	    continue;
+	}
+	frompc = s_lowpc + (fromindex * HASHFRACTION * sizeof(*froms));
+	for (toindex=froms[fromindex]; toindex!=0; toindex=tos[toindex].link) {
+#	    ifdef DEBUG
+		fprintf( stderr ,
+			"[mcleanup] frompc 0x%x selfpc 0x%x count %d\n" ,
+			frompc , tos[toindex].selfpc , tos[toindex].count );
+#	    endif DEBUG
+	    rawarc.raw_frompc = (unsigned long) frompc;
+	    rawarc.raw_selfpc = (unsigned long) tos[toindex].selfpc;
+	    rawarc.raw_count = tos[toindex].count;
+	    write( fd , (char *) &rawarc , sizeof rawarc );
+	}
+    }
+    close( fd );
+}
+
+void
+mcount()
+{
+	register char			*selfpc;
+	register unsigned short		*frompcindex;
+	register struct tostruct	*top;
+	register struct tostruct	*prevtop;
+	register long			toindex;
+
+	/*
+	 *	find the return address for mcount,
+	 *	and the return address for mcount's caller.
+	 */
+
+	/* selfpc = pc pushed by mcount call.
+	   This identifies the function that was just entered.  */
+	selfpc = (void *) __builtin_return_address (0);
+	/* frompcindex = pc in preceding frame.
+	   This identifies the caller of the function just entered.  */
+	frompcindex = (void *) __builtin_return_address (1);
+	/*
+	 *	check that we are profiling
+	 *	and that we aren't recursively invoked.
+	 */
+	if (profiling) {
+		goto out;
+	}
+	profiling++;
+	/*
+	 *	check that frompcindex is a reasonable pc value.
+	 *	for example:	signal catchers get called from the stack,
+	 *			not from text space.  too bad.
+	 */
+	frompcindex = (unsigned short *)((long)frompcindex - (long)s_lowpc);
+	if ((unsigned long)frompcindex > s_textsize) {
+		goto done;
+	}
+	frompcindex =
+	    &froms[((long)frompcindex) / (HASHFRACTION * sizeof(*froms))];
+	toindex = *frompcindex;
+	if (toindex == 0) {
+		/*
+		 *	first time traversing this arc
+		 */
+		toindex = ++tos[0].link;
+		if (toindex >= tolimit) {
+			goto overflow;
+		}
+		*frompcindex = toindex;
+		top = &tos[toindex];
+		top->selfpc = selfpc;
+		top->count = 1;
+		top->link = 0;
+		goto done;
+	}
+	top = &tos[toindex];
+	if (top->selfpc == selfpc) {
+		/*
+		 *	arc at front of chain; usual case.
+		 */
+		top->count++;
+		goto done;
+	}
+	/*
+	 *	have to go looking down chain for it.
+	 *	top points to what we are looking at,
+	 *	prevtop points to previous top.
+	 *	we know it is not at the head of the chain.
+	 */
+	for (; /* goto done */; ) {
+		if (top->link == 0) {
+			/*
+			 *	top is end of the chain and none of the chain
+			 *	had top->selfpc == selfpc.
+			 *	so we allocate a new tostruct
+			 *	and link it to the head of the chain.
+			 */
+			toindex = ++tos[0].link;
+			if (toindex >= tolimit) {
+				goto overflow;
+			}
+			top = &tos[toindex];
+			top->selfpc = selfpc;
+			top->count = 1;
+			top->link = *frompcindex;
+			*frompcindex = toindex;
+			goto done;
+		}
+		/*
+		 *	otherwise, check the next arc on the chain.
+		 */
+		prevtop = top;
+		top = &tos[top->link];
+		if (top->selfpc == selfpc) {
+			/*
+			 *	there it is.
+			 *	increment its count
+			 *	move it to the head of the chain.
+			 */
+			top->count++;
+			toindex = prevtop->link;
+			prevtop->link = top->link;
+			top->link = *frompcindex;
+			*frompcindex = toindex;
+			goto done;
+		}
+
+	}
+done:
+	profiling--;
+	/* and fall through */
+out:
+	return;		/* normal return restores saved registers */
+
+overflow:
+	profiling++; /* halt further profiling */
+#   define	TOLIMIT	"mcount: tos overflow\n"
+	write(2, TOLIMIT, sizeof(TOLIMIT));
+	goto out;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/gmon/gmon.h
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/gmon/gmon.h
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)gmon.h	5.2 (Berkeley) 5/6/91
+ */
+
+#ifndef _GMON_H
+#define _GMON_H
+
+struct phdr {
+    char	*lpc;
+    char	*hpc;
+    int		ncnt;
+};
+
+    /*
+     *	histogram counters are unsigned shorts (according to the kernel).
+     */
+#define	HISTCOUNTER	unsigned short
+
+    /*
+     *	fraction of text space to allocate for histogram counters
+     *	here, 1/2
+     */
+#define	HISTFRACTION	2
+
+    /*
+     *	Fraction of text space to allocate for from hash buckets.
+     *	The value of HASHFRACTION is based on the minimum number of bytes
+     *	of separation between two subroutine call points in the object code.
+     *	Given MIN_SUBR_SEPARATION bytes of separation the value of
+     *	HASHFRACTION is calculated as:
+     *
+     *		HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1);
+     *
+     *	For the VAX, the shortest two call sequence is:
+     *
+     *		calls	$0,(r0)
+     *		calls	$0,(r0)
+     *
+     *	which is separated by only three bytes, thus HASHFRACTION is 
+     *	calculated as:
+     *
+     *		HASHFRACTION = 3 / (2 * 2 - 1) = 1
+     *
+     *	Note that the division above rounds down, thus if MIN_SUBR_FRACTION
+     *	is less than three, this algorithm will not work!
+     */
+#define	HASHFRACTION	1
+
+    /*
+     *	percent of text space to allocate for tostructs
+     *	with a minimum.
+     */
+#define ARCDENSITY	2
+#define MINARCS		50
+
+struct tostruct {
+    char		*selfpc;
+    long		count;
+    unsigned short	link;
+};
+
+    /*
+     *	a raw arc,
+     *	    with pointers to the calling site and the called site
+     *	    and a count.
+     */
+struct rawarc {
+    unsigned long	raw_frompc;
+    unsigned long	raw_selfpc;
+    long		raw_count;
+};
+
+    /*
+     *	general rounding functions.
+     */
+#define ROUNDDOWN(x,y)	(((x)/(y))*(y))
+#define ROUNDUP(x,y)	((((x)+(y)-1)/(y))*(y))
+
+#endif /* _GMON_H */
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/gmon/profil.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/gmon/profil.c
@@ -0,0 +1,110 @@
+/*
+ * profil.c -- user space version of the profil(2) system call
+ * Copyright (C) 1992, 1993 Rick Sladkey <jrs@world.std.com>
+ *
+ * This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ */
+
+/*
+ *     IMPORTANT:
+ *
+ *   This file should never be compiled with -p or -pg!
+ *   It will need special consideration in the Makefile for libc_p.a
+ *   to ensure that it is not compiled with any profiling flags.
+ *
+ *     Limitations:
+ *
+ * - Any program that tries to use SIGPROF itimers and profil at the
+ *   same time won't work.
+ *
+ * - The user's program is free to trash our handler with a call to
+ *   signal or sigaction.
+ *
+ * - Calling profil with an invalid buffer will cause a core dump instead
+ *   of just disabling profiling.
+ *
+ * - The precision of the histogram is worse than with true kernel
+ *   profiling.
+ *
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+static struct sigaction old_sa;
+static struct itimerval old_it;
+
+static unsigned long prof_buf;
+static int prof_bufsiz;
+static int prof_offset;
+static int prof_scale = 0;
+
+/*
+ * This depends a lot on the stack at the time the signal handler
+ * is invoked.  For Linux-0.99.8 and before eip was the seventh
+ * argument.  For Linux-0.99.9 and later it is the fourteenth.
+ * I think.  For Linux-0.99.13 it is the sixteenth.  It's a
+ * continuing mystery.
+ */
+  
+static void
+_profil_handler(int signr)
+{
+	unsigned long pc, spot;
+	unsigned long eip = ((unsigned long *) &signr)[15];
+
+#ifdef PROFIL_DEBUG
+	printf("eip = %#x\n", eip);
+#endif
+	pc = eip - prof_offset;
+	spot = (prof_scale*(pc >> 16)
+		+ ((prof_scale*(pc & (0x10000 - 1))) >> 16)) & ~1;
+	if (spot < prof_bufsiz)
+		++*((unsigned short *) (spot + prof_buf));
+}
+
+int
+profil(char *buf, int bufsiz, int offset, int scale)
+{
+	struct sigaction new_sa;
+	struct itimerval new_it;
+	int old_scale = prof_scale;
+
+	if (!buf || bufsiz == 0 || scale < 2) {
+		if (prof_scale) {
+			setitimer(ITIMER_PROF, &old_it, &new_it);
+			sigaction(SIGPROF, &old_sa, &new_sa);
+		}
+		prof_scale = 0;
+	}
+	else {
+		prof_buf = (unsigned long) buf;
+		prof_bufsiz = bufsiz;
+		prof_offset = offset;
+		prof_scale = scale;
+		if (!old_scale) {
+			prof_scale = scale;
+			new_sa.sa_handler =
+				(void (*)(int)) _profil_handler;
+			new_sa.sa_mask = 0;
+#ifdef SA_RESTART
+			new_sa.sa_flags = SA_RESTART;
+#else
+			new_sa.sa_flags = 0;
+#endif
+			new_it.it_interval.tv_sec = 0;
+			new_it.it_interval.tv_usec = 1;
+			new_it.it_value.tv_sec = 0;
+			new_it.it_value.tv_usec = 1;
+			sigaction(SIGPROF, &new_sa, &old_sa);
+			setitimer(ITIMER_PROF, &new_it, &old_it);
+		}
+	}
+	return 0;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/ieee.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/ieee.c
@@ -0,0 +1,3 @@
+#include <fpu_control.h>
+
+unsigned short __fpu_control = _FPU_IEEE;
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/libc_exit.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/libc_exit.c
@@ -0,0 +1,29 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifdef PTHREAD_KERNEL
+#pragma weak machdep_sys__exit = __machdep_sys__exit
+
+void
+__machdep_sys__exit(int exit_code)
+#else /* PTHREAD_KERNEL */
+
+#ifdef _POSIX_THREADS
+#pragma weak _exit
+#endif
+
+void
+_exit(int exit_code)
+#endif /* PTHREAD_KERNEL */
+{
+    int result;
+    
+    __asm__ volatile ("mov %0, %%g1\n\t"
+		      "mov %2, %%o0\n\t"
+		      "t 0x10\n\t"
+		      : "r=" (result)
+		      : "0" (SYS_exit), "r" (exit_code)
+	              : "o0", "g1");
+}
+
+
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/Makefile
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/Makefile
@@ -0,0 +1,36 @@
+#
+# This is Makefile of the math lib for Linux for the Sparc
+#
+
+MATH=true
+
+override DEBUG=false
+override PROFILE=false
+
+TOPDIR=../../../..
+
+include $(TOPDIR)/Makeconfig
+include $(TOPDIR)/Makerules
+
+INC_CFLAGS = -I.
+MATHFLAGS=
+
+BASE_CFLAGS := $(BASE_CFLAGS) $(MATHFLAGS)
+
+SRC1S= __copysign.c __infnan.c isinf.c __isnan.c __rint.c \
+	acos.c acosh.c asin.c atanh.c erf.c frexp.c \
+	j0.c j1.c jn.c lgamma.c log.c log10.c log1p.c pow.c sqrt.c \
+	asinh.c atan.c atan2.c sincos.c cosh.c exp.c \
+	fabs.c fmod.c hypot.c sinh.c tan.c tanh.c logb.c \
+	scalb.c __scalb.c drem.c modf.c exp__E.c __expm1.c  \
+	floor.c ceil.c log__L.c rint.c
+
+SRC2S=
+
+DIRS:=
+SRCS=$(SRC1S) $(SRC2S)
+ASMS= $(SRC1S:.c=.s) $(SRC2S:.S=.s)
+OBJS= $(SRC1S:.c=.o) $(SRC2S:.S=.o)
+ALIASES:=
+
+include $(TOPDIR)/Maketargets
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/__copysign.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/__copysign.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <math.h>
+
+/* Return X with its signed changed to Y's.  */
+double
+DEFUN(__copysign, (x, y), double x AND double y)
+{
+  x = fabs (x);
+  return y < 0 ? - x : x;
+}
+#include <gnu-stabs.h>
+#ifdef weak_alias
+weak_alias (__copysign, copysign);
+#endif
+
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/__expm1.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/__expm1.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)expm1.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* EXPM1(X)
+ * RETURN THE EXPONENTIAL OF X MINUS ONE
+ * DOUBLE PRECISION (IEEE 53 BITS, VAX D FORMAT 56 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85; 
+ * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/21/85, 4/16/85.
+ *
+ * Required system supported functions:
+ *	scalb(x,n)	
+ *	copysign(x,y)	
+ *	finite(x)
+ *
+ * Kernel function:
+ *	exp__E(x,c)
+ *
+ * Method:
+ *	1. Argument Reduction: given the input x, find r and integer k such 
+ *	   that
+ *	                   x = k*ln2 + r,  |r| <= 0.5*ln2 .  
+ *	   r will be represented as r := z+c for better accuracy.
+ *
+ *	2. Compute EXPM1(r)=exp(r)-1 by 
+ *
+ *			EXPM1(r=z+c) := z + exp__E(z,c)
+ *
+ *	3. EXPM1(x) =  2^k * ( EXPM1(r) + 1-2^-k ).
+ *
+ * 	Remarks: 
+ *	   1. When k=1 and z < -0.25, we use the following formula for
+ *	      better accuracy:
+ *			EXPM1(x) = 2 * ( (z+0.5) + exp__E(z,c) )
+ *	   2. To avoid rounding error in 1-2^-k where k is large, we use
+ *			EXPM1(x) = 2^k * { [z+(exp__E(z,c)-2^-k )] + 1 }
+ *	      when k>56. 
+ *
+ * Special cases:
+ *	EXPM1(INF) is INF, EXPM1(NaN) is NaN;
+ *	EXPM1(-INF)= -1;
+ *	for finite argument, only EXPM1(0)=0 is exact.
+ *
+ * Accuracy:
+ *	EXPM1(x) returns the exact (exp(x)-1) nearly rounded. In a test run with
+ *	1,166,000 random arguments on a VAX, the maximum observed error was
+ *	.872 ulps (units of the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi,  6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000)
+vc(ln2lo,  1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(lnhuge, 9.4961163736712506989E1   ,ec1d,43bd,9010,a73e,   7, .BDEC1DA73E9010)
+vc(invln2, 1.4426950408889634148E0   ,aa3b,40b8,17f1,295c,   1, .B8AA3B295C17F1)
+
+ic(ln2hi,  6.9314718036912381649E-1,   -1, 1.62E42FEE00000)
+ic(ln2lo,  1.9082149292705877000E-10, -33, 1.A39EF35793C76)
+ic(lnhuge, 7.1602103751842355450E2,     9, 1.6602B15B7ECF2)
+ic(invln2, 1.4426950408889633870E0,     0, 1.71547652B82FE)
+
+#ifdef vccast
+#define	ln2hi	vccast(ln2hi)
+#define	ln2lo	vccast(ln2lo)
+#define	lnhuge	vccast(lnhuge)
+#define	invln2	vccast(invln2)
+#endif
+
+extern double scalb();
+
+double expm1(x)
+double x;
+{
+	const static double one=1.0, half=1.0/2.0; 
+	double  z,hi,lo,c;
+	int k;
+#if defined(vax)||defined(tahoe)
+	static prec=56;
+#else	/* defined(vax)||defined(tahoe) */
+	static prec=53;
+#endif	/* defined(vax)||defined(tahoe) */
+
+#if !defined(vax)&&!defined(tahoe)
+	if(x!=x) return(x);	/* x is NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+
+	if( x <= lnhuge ) {
+		if( x >= -40.0 ) {
+
+		    /* argument reduction : x - k*ln2 */
+			k= invln2 *x+copysign(0.5,x);	/* k=NINT(x/ln2) */
+			hi=x-k*ln2hi ; 
+			z=hi-(lo=k*ln2lo);
+			c=(hi-z)-lo;
+
+			if(k==0) return(z+__exp__E(z,c));
+			if(k==1)
+			    if(z< -0.25) 
+				{x=z+half;x +=__exp__E(z,c); return(x+x);}
+			    else
+				{z+=__exp__E(z,c); x=half+z; return(x+x);}
+		    /* end of k=1 */
+
+			else {
+			    if(k<=prec)
+			      { x=one-scalb(one,-k); z += __exp__E(z,c);}
+			    else if(k<100)
+			      { x = __exp__E(z,c)-scalb(one,-k); x+=z; z=one;}
+			    else 
+			      { x = __exp__E(z,c)+z; z=one;}
+
+			    return (scalb(x+z,k));  
+			}
+		}
+		/* end of x > lnunfl */
+
+		else 
+		     /* expm1(-big#) rounded to -1 (inexact) */
+		     if(finite(x))  
+			 { ln2hi+ln2lo; return(-one);}
+
+		     /* expm1(-INF) is -1 */
+		     else return(-one);
+	}
+	/* end of x < lnhuge */
+
+	else 
+	/*  expm1(INF) is INF, expm1(+big#) overflows to INF */
+	    return( finite(x) ?  scalb(one,5000) : x);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/__infnan.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/__infnan.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <math.h>
+
+/* Deal with an infinite or NaN result.
+   If ERROR is ERANGE, result is +Inf;
+   if ERROR is - ERANGE, result is -Inf;
+   otherwise result is NaN.
+   This will set `errno' to either ERANGE or EDOM,
+   and may return an infinity or NaN, or may do something else.  */
+double
+DEFUN(__infnan, (error), int error)
+{
+  switch (error)
+    {
+    case ERANGE:
+      errno = ERANGE;
+      return HUGE_VAL;
+
+    case - ERANGE:
+      errno = ERANGE;
+      return - HUGE_VAL;
+
+    default:
+      errno = EDOM;
+      return 0.0;
+    }
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/__isnan.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/__isnan.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <math.h>
+
+/* Return nonzero if VALUE is not a number.  */
+int
+DEFUN(__isnan, (value), double value)
+{
+  return value != value;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/__lstat.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/__lstat.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <gnu-stabs.h>
+
+function_alias (__lstat, __stat, int, (file, buf),
+		DEFUN(__lstat, (file, buf),
+		      CONST char *file AND struct stat *buf))
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/__rint.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/__rint.c
@@ -0,0 +1,90 @@
+/* snarfed from BSD common_source/floor.c:
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)floor.c	5.7 (Berkeley) 10/9/90";
+#endif /* not lint */
+
+#include "mathimpl.h"
+
+vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
+
+ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */
+
+#ifdef vccast
+#define	L	vccast(L)
+#endif
+
+/*
+ * algorithm for rint(x) in pseudo-pascal form ...
+ *
+ * real rint(x): real x;
+ *	... delivers integer nearest x in direction of prevailing rounding
+ *	... mode
+ * const	L = (last consecutive integer)/2
+ * 	  = 2**55; for VAX D
+ * 	  = 2**52; for IEEE 754 Double
+ * real	s,t;
+ * begin
+ * 	if x != x then return x;		... NaN
+ * 	if |x| >= L then return x;		... already an integer
+ * 	s := copysign(L,x);
+ * 	t := x + s;				... = (x+s) rounded to integer
+ * 	return t - s
+ * end;
+ *
+ * Note: Inexact will be signaled if x is not an integer, as is
+ *	customary for IEEE 754.  No other signal can be emitted.
+ */
+double
+__rint(x)
+double x;
+{
+	double s,t;
+	const double one = 1.0;
+
+#if !defined(vax)&&!defined(tahoe)
+	if (x != x)				/* NaN */
+		return (x);
+#endif	/* !defined(vax)&&!defined(tahoe) */
+	if (copysign(x,one) >= L)		/* already an integer */
+	    return (x);
+	s = copysign(L,x);
+	t = x + s;				/* x+s rounded to integer */
+	return (t - s);
+}
+#include <gnu-stabs.h>
+#ifdef weak_alias
+weak_alias (__rint, rint);
+#endif
+
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/__scalb.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/__scalb.c
@@ -0,0 +1,25 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <gnu-stabs.h>
+#include <math.h>
+
+#undef	__scalb
+function_alias(__scalb, ldexp, __CONSTVALUE double, (x, n),
+	       DEFUN(__scalb, (x, n), double x AND int n))
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/acos.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/acos.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <math.h>
+
+/* Return the inverse cosine of X.  */
+double
+DEFUN(acos, (x), double x)
+{
+  double t;
+
+  if (__isnan(x))
+    {
+      errno = EDOM;
+      return x;
+    }
+
+  if (x == -1.0)
+    /* If X is -1, the general formula blows up (zero divided by zero loses),
+       but we know that acos(-1) = pi.  */
+    t = atan2(1.0, 0.0);
+  else
+    t = atan2(sqrt((1.0 - x) / (1.0 + x)), 1.0);
+  return t + t;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/acosh.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/acosh.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)acosh.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ACOSH(X)
+ * RETURN THE INVERSE HYPERBOLIC COSINE OF X
+ * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 2/16/85;
+ * REVISED BY K.C. NG on 3/6/85, 3/24/85, 4/16/85, 8/17/85.
+ *
+ * Required system supported functions :
+ *	sqrt(x)
+ *
+ * Required kernel function:
+ *	log1p(x) 		...return log(1+x)
+ *
+ * Method :
+ *	Based on 
+ *		acosh(x) = log [ x + sqrt(x*x-1) ]
+ *	we have
+ *		acosh(x) := log1p(x)+ln2,	if (x > 1.0E20); else		
+ *		acosh(x) := log1p( sqrt(x-1) * (sqrt(x-1) + sqrt(x+1)) ) .
+ *	These formulae avoid the over/underflow complication.
+ *
+ * Special cases:
+ *	acosh(x) is NaN with signal if x<1.
+ *	acosh(NaN) is NaN without signal.
+ *
+ * Accuracy:
+ *	acosh(x) returns the exact inverse hyperbolic cosine of x nearly 
+ *	rounded. In a test run with 512,000 random arguments on a VAX, the
+ *	maximum observed error was 3.30 ulps (units of the last place) at
+ *	x=1.0070493753568216 .
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+
+ic(ln2hi, 6.9314718036912381649E-1,  -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10,-33, 1.A39EF35793C76)
+
+#ifdef vccast
+#define    ln2hi    vccast(ln2hi)
+#define    ln2lo    vccast(ln2lo)
+#endif
+
+double acosh(x)
+double x;
+{	
+	double t,big=1.E20; /* big+1==big */
+
+#if !defined(vax)&&!defined(tahoe)
+	if(x!=x) return(x);	/* x is NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+
+    /* return log1p(x) + log(2) if x is large */
+	if(x>big) {t=log1p(x)+ln2lo; return(t+ln2hi);} 
+
+	t=sqrt(x-1.0);
+	return(log1p(t*(t+sqrt(x+1.0))));
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/asin.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/asin.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <math.h>
+
+/* Return the inverse sine of X.  */
+double
+DEFUN(asin, (x), double x)
+{
+  double abs_x;
+
+  if (__isnan(x))
+    {
+      errno = EDOM;
+      return x;
+    }
+
+  abs_x = fabs(x);
+
+  if (abs_x <= 0.5)
+    return atan2(x, sqrt(1.0 - (x * x)));
+  else
+    {
+      double t = 1.0 - abs_x;
+      return atan2(x, sqrt((t + t) - (t * t)));
+    }
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/asincos.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/asincos.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)asincos.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ASIN(X)
+ * RETURNS ARC SINE OF X
+ * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits)
+ * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85.
+ *
+ * Required system supported functions:
+ *	copysign(x,y)
+ *	sqrt(x)
+ *
+ * Required kernel function:
+ *	atan2(y,x) 
+ *
+ * Method :                  
+ *	asin(x) = atan2(x,sqrt(1-x*x)); for better accuracy, 1-x*x is 
+ *		  computed as follows
+ *			1-x*x                     if x <  0.5, 
+ *			2*(1-|x|)-(1-|x|)*(1-|x|) if x >= 0.5.
+ *
+ * Special cases:
+ *	if x is NaN, return x itself;
+ *	if |x|>1, return NaN.
+ *
+ * Accuracy:
+ * 1)  If atan2() uses machine PI, then
+ * 
+ *	asin(x) returns (PI/pi) * (the exact arc sine of x) nearly rounded;
+ *	and PI is the exact pi rounded to machine precision (see atan2 for
+ *      details):
+ *
+ *	in decimal:
+ *		pi = 3.141592653589793 23846264338327 ..... 
+ *    53 bits   PI = 3.141592653589793 115997963 ..... ,
+ *    56 bits   PI = 3.141592653589793 227020265 ..... ,  
+ *
+ *	in hexadecimal:
+ *		pi = 3.243F6A8885A308D313198A2E....
+ *    53 bits   PI = 3.243F6A8885A30  =  2 * 1.921FB54442D18	error=.276ulps
+ *    56 bits   PI = 3.243F6A8885A308 =  4 * .C90FDAA22168C2    error=.206ulps
+ *	
+ *	In a test run with more than 200,000 random arguments on a VAX, the 
+ *	maximum observed error in ulps (units in the last place) was
+ *	2.06 ulps.      (comparing against (PI/pi)*(exact asin(x)));
+ *
+ * 2)  If atan2() uses true pi, then
+ *
+ *	asin(x) returns the exact asin(x) with error below about 2 ulps.
+ *
+ *	In a test run with more than 1,024,000 random arguments on a VAX, the 
+ *	maximum observed error in ulps (units in the last place) was
+ *      1.99 ulps.
+ */
+
+double asin(x)
+double x;
+{
+	double s,t,copysign(),atan2(),sqrt(),one=1.0;
+#if !defined(vax)&&!defined(tahoe)
+	if(x!=x) return(x);	/* x is NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+	s=copysign(x,one);
+	if(s <= 0.5)
+	    return(atan2(x,sqrt(one-x*x)));
+	else 
+	    { t=one-s; s=t+t; return(atan2(x,sqrt(s-t*t))); }
+
+}
+
+/* ACOS(X)
+ * RETURNS ARC COS OF X
+ * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits)
+ * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85.
+ *
+ * Required system supported functions:
+ *	copysign(x,y)
+ *	sqrt(x)
+ *
+ * Required kernel function:
+ *	atan2(y,x) 
+ *
+ * Method :                  
+ *			      ________
+ *                           / 1 - x
+ *	acos(x) = 2*atan2(  / -------- , 1 ) .
+ *                        \/   1 + x
+ *
+ * Special cases:
+ *	if x is NaN, return x itself;
+ *	if |x|>1, return NaN.
+ *
+ * Accuracy:
+ * 1)  If atan2() uses machine PI, then
+ * 
+ *	acos(x) returns (PI/pi) * (the exact arc cosine of x) nearly rounded;
+ *	and PI is the exact pi rounded to machine precision (see atan2 for
+ *      details):
+ *
+ *	in decimal:
+ *		pi = 3.141592653589793 23846264338327 ..... 
+ *    53 bits   PI = 3.141592653589793 115997963 ..... ,
+ *    56 bits   PI = 3.141592653589793 227020265 ..... ,  
+ *
+ *	in hexadecimal:
+ *		pi = 3.243F6A8885A308D313198A2E....
+ *    53 bits   PI = 3.243F6A8885A30  =  2 * 1.921FB54442D18	error=.276ulps
+ *    56 bits   PI = 3.243F6A8885A308 =  4 * .C90FDAA22168C2    error=.206ulps
+ *	
+ *	In a test run with more than 200,000 random arguments on a VAX, the 
+ *	maximum observed error in ulps (units in the last place) was
+ *	2.07 ulps.      (comparing against (PI/pi)*(exact acos(x)));
+ *
+ * 2)  If atan2() uses true pi, then
+ *
+ *	acos(x) returns the exact acos(x) with error below about 2 ulps.
+ *
+ *	In a test run with more than 1,024,000 random arguments on a VAX, the 
+ *	maximum observed error in ulps (units in the last place) was
+ *	2.15 ulps.
+ */
+
+double acos(x)
+double x;
+{
+	double t,copysign(),atan2(),sqrt(),one=1.0;
+#if !defined(vax)&&!defined(tahoe)
+	if(x!=x) return(x);
+#endif	/* !defined(vax)&&!defined(tahoe) */
+	if( x != -1.0)
+	    t=atan2(sqrt((one-x)/(one+x)),one);
+	else
+	    t=atan2(one,0.0);	/* t = PI/2 */
+	return(t+t);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/asinh.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/asinh.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)asinh.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ASINH(X)
+ * RETURN THE INVERSE HYPERBOLIC SINE OF X
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 2/16/85;
+ * REVISED BY K.C. NG on 3/7/85, 3/24/85, 4/16/85.
+ *
+ * Required system supported functions :
+ *	copysign(x,y)
+ *	sqrt(x)
+ *
+ * Required kernel function:
+ *	log1p(x) 		...return log(1+x)
+ *
+ * Method :
+ *	Based on 
+ *		asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+ *	we have
+ *	asinh(x) := x  if  1+x*x=1,
+ *		 := sign(x)*(log1p(x)+ln2))	 if sqrt(1+x*x)=x, else
+ *		 := sign(x)*log1p(|x| + |x|/(1/|x| + sqrt(1+(1/|x|)^2)) )  
+ *
+ * Accuracy:
+ *	asinh(x) returns the exact inverse hyperbolic sine of x nearly rounded.
+ *	In a test run with 52,000 random arguments on a VAX, the maximum 
+ *	observed error was 1.58 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+
+ic(ln2hi, 6.9314718036912381649E-1,   -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76)
+
+#ifdef vccast
+#define    ln2hi    vccast(ln2hi)
+#define    ln2lo    vccast(ln2lo)
+#endif
+
+double asinh(x)
+double x;
+{	
+	double t,s;
+	const static double	small=1.0E-10,	/* fl(1+small*small) == 1 */
+				big  =1.0E20,	/* fl(1+big) == big */
+				one  =1.0   ;	
+
+#if !defined(vax)&&!defined(tahoe)
+	if(x!=x) return(x);	/* x is NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+	if((t=copysign(x,one))>small) 
+	    if(t<big) {
+	     	s=one/t; return(copysign(log1p(t+t/(s+sqrt(one+s*s))),x)); }
+	    else	/* if |x| > big */
+		{s=log1p(t)+ln2lo; return(copysign(s+ln2hi,x));}
+	else	/* if |x| < small */
+	    return(x);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/atan.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/atan.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <math.h>
+
+/* Return the inverse tangent of X.  */
+__CONSTVALUE double
+DEFUN(atan, (x), register double x)
+{
+  return atan2(x, 1.0);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/atan2.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/atan2.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)atan2.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ATAN2(Y,X)
+ * RETURN ARG (X+iY)
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85; 
+ * REVISED BY K.C. NG on 2/7/85, 2/13/85, 3/7/85, 3/30/85, 6/29/85.
+ *
+ * Required system supported functions :
+ *	copysign(x,y)
+ *	scalb(x,y)
+ *	logb(x)
+ *	
+ * Method :
+ *	1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ *	2. Reduce x to positive by (if x and y are unexceptional): 
+ *		ARG (x+iy) = arctan(y/x)   	   ... if x > 0,
+ *		ARG (x+iy) = pi - arctan[y/(-x)]   ... if x < 0,
+ *	3. According to the integer k=4t+0.25 truncated , t=y/x, the argument 
+ *	   is further reduced to one of the following intervals and the 
+ *	   arctangent of y/x is evaluated by the corresponding formula:
+ *
+ *         [0,7/16]	   atan(y/x) = t - t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
+ *	   [7/16,11/16]    atan(y/x) = atan(1/2) + atan( (y-x/2)/(x+y/2) )
+ *	   [11/16.19/16]   atan(y/x) = atan( 1 ) + atan( (y-x)/(x+y) )
+ *	   [19/16,39/16]   atan(y/x) = atan(3/2) + atan( (y-1.5x)/(x+1.5y) )
+ *	   [39/16,INF]     atan(y/x) = atan(INF) + atan( -x/y )
+ *
+ * Special cases:
+ * Notations: atan2(y,x) == ARG (x+iy) == ARG(x,y).
+ *
+ *	ARG( NAN , (anything) ) is NaN;
+ *	ARG( (anything), NaN ) is NaN;
+ *	ARG(+(anything but NaN), +-0) is +-0  ;
+ *	ARG(-(anything but NaN), +-0) is +-PI ;
+ *	ARG( 0, +-(anything but 0 and NaN) ) is +-PI/2;
+ *	ARG( +INF,+-(anything but INF and NaN) ) is +-0 ;
+ *	ARG( -INF,+-(anything but INF and NaN) ) is +-PI;
+ *	ARG( +INF,+-INF ) is +-PI/4 ;
+ *	ARG( -INF,+-INF ) is +-3PI/4;
+ *	ARG( (anything but,0,NaN, and INF),+-INF ) is +-PI/2;
+ *
+ * Accuracy:
+ *	atan2(y,x) returns (PI/pi) * the exact ARG (x+iy) nearly rounded, 
+ *	where
+ *
+ *	in decimal:
+ *		pi = 3.141592653589793 23846264338327 ..... 
+ *    53 bits   PI = 3.141592653589793 115997963 ..... ,
+ *    56 bits   PI = 3.141592653589793 227020265 ..... ,  
+ *
+ *	in hexadecimal:
+ *		pi = 3.243F6A8885A308D313198A2E....
+ *    53 bits   PI = 3.243F6A8885A30  =  2 * 1.921FB54442D18	error=.276ulps
+ *    56 bits   PI = 3.243F6A8885A308 =  4 * .C90FDAA22168C2    error=.206ulps
+ *	
+ *	In a test run with 356,000 random argument on [-1,1] * [-1,1] on a
+ *	VAX, the maximum observed error was 1.41 ulps (units of the last place)
+ *	compared with (PI/pi)*(the exact ARG(x+iy)).
+ *
+ * Note:
+ *	We use machine PI (the true pi rounded) in place of the actual
+ *	value of pi for all the trig and inverse trig functions. In general, 
+ *	if trig is one of sin, cos, tan, then computed trig(y) returns the 
+ *	exact trig(y*pi/PI) nearly rounded; correspondingly, computed arctrig 
+ *	returns the exact arctrig(y)*PI/pi nearly rounded. These guarantee the 
+ *	trig functions have period PI, and trig(arctrig(x)) returns x for
+ *	all critical values x.
+ *	
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(athfhi, 4.6364760900080611433E-1  ,6338,3fed,da7b,2b0d,  -1, .ED63382B0DDA7B)
+vc(athflo, 1.9338828231967579916E-19 ,5005,2164,92c0,9cfe, -62, .E450059CFE92C0)
+vc(PIo4,   7.8539816339744830676E-1  ,0fda,4049,68c2,a221,   0, .C90FDAA22168C2)
+vc(at1fhi, 9.8279372324732906796E-1  ,985e,407b,b4d9,940f,   0, .FB985E940FB4D9)
+vc(at1flo,-3.5540295636764633916E-18 ,1edc,a383,eaea,34d6, -57,-.831EDC34D6EAEA)
+vc(PIo2,   1.5707963267948966135E0   ,0fda,40c9,68c2,a221,   1, .C90FDAA22168C2)
+vc(PI,     3.1415926535897932270E0   ,0fda,4149,68c2,a221,   2, .C90FDAA22168C2)
+vc(a1,     3.3333333333333473730E-1  ,aaaa,3faa,ab75,aaaa,  -1, .AAAAAAAAAAAB75)
+vc(a2,    -2.0000000000017730678E-1  ,cccc,bf4c,946e,cccd,  -2,-.CCCCCCCCCD946E)
+vc(a3,     1.4285714286694640301E-1  ,4924,3f12,4262,9274,  -2, .92492492744262)
+vc(a4,    -1.1111111135032672795E-1  ,8e38,bee3,6292,ebc6,  -3,-.E38E38EBC66292)
+vc(a5,     9.0909091380563043783E-2  ,2e8b,3eba,d70c,b31b,  -3, .BA2E8BB31BD70C)
+vc(a6,    -7.6922954286089459397E-2  ,89c8,be9d,7f18,27c3,  -3,-.9D89C827C37F18)
+vc(a7,     6.6663180891693915586E-2  ,86b4,3e88,9e58,ae37,  -3, .8886B4AE379E58)
+vc(a8,    -5.8772703698290408927E-2  ,bba5,be70,a942,8481,  -4,-.F0BBA58481A942)
+vc(a9,     5.2170707402812969804E-2  ,b0f3,3e55,13ab,a1ab,  -4, .D5B0F3A1AB13AB)
+vc(a10,   -4.4895863157820361210E-2  ,e4b9,be37,048f,7fd1,  -4,-.B7E4B97FD1048F)
+vc(a11,    3.3006147437343875094E-2  ,3174,3e07,2d87,3cf7,  -4, .8731743CF72D87)
+vc(a12,   -1.4614844866464185439E-2  ,731a,bd6f,76d9,2f34,  -6,-.EF731A2F3476D9)
+
+ic(athfhi, 4.6364760900080609352E-1  ,  -2,  1.DAC670561BB4F)
+ic(athflo, 4.6249969567426939759E-18 , -58,  1.5543B8F253271)
+ic(PIo4,   7.8539816339744827900E-1  ,  -1,  1.921FB54442D18)
+ic(at1fhi, 9.8279372324732905408E-1  ,  -1,  1.F730BD281F69B)
+ic(at1flo,-2.4407677060164810007E-17 , -56, -1.C23DFEFEAE6B5)
+ic(PIo2,   1.5707963267948965580E0   ,   0,  1.921FB54442D18)
+/* ic(PI,     3.1415926535897931160E0   ,   1,  1.921FB54442D18) */
+ic(a1,     3.3333333333333942106E-1  ,  -2,  1.55555555555C3)
+ic(a2,    -1.9999999999979536924E-1  ,  -3, -1.9999999997CCD)
+ic(a3,     1.4285714278004377209E-1  ,  -3,  1.24924921EC1D7)
+ic(a4,    -1.1111110579344973814E-1  ,  -4, -1.C71C7059AF280)
+ic(a5,     9.0908906105474668324E-2  ,  -4,  1.745CE5AA35DB2)
+ic(a6,    -7.6919217767468239799E-2  ,  -4, -1.3B0FA54BEC400)
+ic(a7,     6.6614695906082474486E-2  ,  -4,  1.10DA924597FFF)
+ic(a8,    -5.8358371008508623523E-2  ,  -5, -1.DE125FDDBD793)
+ic(a9,     4.9850617156082015213E-2  ,  -5,  1.9860524BDD807)
+ic(a10,   -3.6700606902093604877E-2  ,  -5, -1.2CA6C04C6937A)
+ic(a11,    1.6438029044759730479E-2  ,  -6,  1.0D52174A1BB54)
+
+#ifdef vccast
+#define	athfhi	vccast(athfhi)
+#define	athflo	vccast(athflo)
+#define	PIo4	vccast(PIo4)
+#define	at1fhi	vccast(at1fhi)
+#define	at1flo	vccast(at1flo)
+#define	PIo2	vccast(PIo2)
+#define	PI	vccast(PI)
+#define	a1	vccast(a1)
+#define	a2	vccast(a2)
+#define	a3	vccast(a3)
+#define	a4	vccast(a4)
+#define	a5	vccast(a5)
+#define	a6	vccast(a6)
+#define	a7	vccast(a7)
+#define	a8	vccast(a8)
+#define	a9	vccast(a9)
+#define	a10	vccast(a10)
+#define	a11	vccast(a11)
+#define	a12	vccast(a12)
+#endif
+
+extern double logb(), scalb();
+
+double atan2(y,x)
+double  y,x;
+{  
+	static const double zero=0, one=1, small=1.0E-9, big=1.0E18;
+	double t,z,signy,signx,hi,lo;
+	int k,m;
+
+#if !defined(vax)&&!defined(tahoe)
+    /* if x or y is NAN */
+	if(x!=x) return(x); if(y!=y) return(y);
+#endif	/* !defined(vax)&&!defined(tahoe) */
+
+    /* copy down the sign of y and x */
+	signy = copysign(one,y) ;  
+	signx = copysign(one,x) ;  
+
+    /* if x is 1.0, goto begin */
+	if(x==1) { y=copysign(y,one); t=y; if(finite(t)) goto begin;}
+
+    /* when y = 0 */
+	if(y==zero) return((signx==one)?y:copysign(PI,signy));
+
+    /* when x = 0 */
+	if(x==zero) return(copysign(PIo2,signy));
+	    
+    /* when x is INF */
+	if(!finite(x))
+	    if(!finite(y)) 
+		return(copysign((signx==one)?PIo4:3*PIo4,signy));
+	    else
+		return(copysign((signx==one)?zero:PI,signy));
+
+    /* when y is INF */
+	if(!finite(y)) return(copysign(PIo2,signy));
+
+    /* compute y/x */
+	x=copysign(x,one); 
+	y=copysign(y,one); 
+	if((m=(k=logb(y))-logb(x)) > 60) t=big+big; 
+	    else if(m < -80 ) t=y/x;
+	    else { t = y/x ; y = scalb(y,-k); x=scalb(x,-k); }
+
+    /* begin argument reduction */
+begin:
+	if (t < 2.4375) {		 
+
+	/* truncate 4(t+1/16) to integer for branching */
+	    k = 4 * (t+0.0625);
+	    switch (k) {
+
+	    /* t is in [0,7/16] */
+	    case 0:                    
+	    case 1:
+		if (t < small) 
+		    { big + small ;  /* raise inexact flag */
+		      return (copysign((signx>zero)?t:PI-t,signy)); }
+
+		hi = zero;  lo = zero;  break;
+
+	    /* t is in [7/16,11/16] */
+	    case 2:                    
+		hi = athfhi; lo = athflo;
+		z = x+x;
+		t = ( (y+y) - x ) / ( z +  y ); break;
+
+	    /* t is in [11/16,19/16] */
+	    case 3:                    
+	    case 4:
+		hi = PIo4; lo = zero;
+		t = ( y - x ) / ( x + y ); break;
+
+	    /* t is in [19/16,39/16] */
+	    default:                   
+		hi = at1fhi; lo = at1flo;
+		z = y-x; y=y+y+y; t = x+x;
+		t = ( (z+z)-x ) / ( t + y ); break;
+	    }
+	}
+	/* end of if (t < 2.4375) */
+
+	else                           
+	{
+	    hi = PIo2; lo = zero;
+
+	    /* t is in [2.4375, big] */
+	    if (t <= big)  t = - x / y;
+
+	    /* t is in [big, INF] */
+	    else          
+	      { big+small;	/* raise inexact flag */
+		t = zero; }
+	}
+    /* end of argument reduction */
+
+    /* compute atan(t) for t in [-.4375, .4375] */
+	z = t*t;
+#if defined(vax)||defined(tahoe)
+	z = t*(z*(a1+z*(a2+z*(a3+z*(a4+z*(a5+z*(a6+z*(a7+z*(a8+
+			z*(a9+z*(a10+z*(a11+z*a12))))))))))));
+#else	/* defined(vax)||defined(tahoe) */
+	z = t*(z*(a1+z*(a2+z*(a3+z*(a4+z*(a5+z*(a6+z*(a7+z*(a8+
+			z*(a9+z*(a10+z*a11)))))))))));
+#endif	/* defined(vax)||defined(tahoe) */
+	z = lo - z; z += t; z += hi;
+
+	return(copysign((signx>zero)?z:PI-z,signy));
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/atanh.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/atanh.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)atanh.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ATANH(X)
+ * RETURN THE HYPERBOLIC ARC TANGENT OF X
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85; 
+ * REVISED BY K.C. NG on 2/7/85, 3/7/85, 8/18/85.
+ *
+ * Required kernel function:
+ *	log1p(x) 	...return log(1+x)
+ *
+ * Method :
+ *	Return 
+ *                          1              2x                          x
+ *		atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ *                          2             1 - x                      1 - x
+ *
+ * Special cases:
+ *	atanh(x) is NaN if |x| > 1 with signal;
+ *	atanh(NaN) is that NaN with no signal;
+ *	atanh(+-1) is +-INF with signal.
+ *
+ * Accuracy:
+ *	atanh(x) returns the exact hyperbolic arc tangent of x nearly rounded.
+ *	In a test run with 512,000 random arguments on a VAX, the maximum
+ *	observed error was 1.87 ulps (units in the last place) at
+ *	x= -3.8962076028810414000e-03.
+ */
+#include "mathimpl.h"
+
+#if defined(vax)||defined(tahoe)
+#include <errno.h>
+#endif	/* defined(vax)||defined(tahoe) */
+
+double atanh(x)
+double x;
+{
+	double z;
+	z = copysign(0.5,x);
+	x = copysign(x,1.0);
+#if defined(vax)||defined(tahoe)
+	if (x == 1.0) {
+	    return(copysign(1.0,z)*infnan(ERANGE));	/* sign(x)*INF */
+	}
+#endif	/* defined(vax)||defined(tahoe) */
+	x = x/(1.0-x);
+	return( z*log1p(x+x) );
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/cabs.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/cabs.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <math.h>
+
+double
+DEFUN(cabs, (z), struct __cabs_complex z)
+{
+  return hypot (z.__x, z.__y);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/ceil.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/ceil.c
@@ -0,0 +1,68 @@
+/* snarfed from BSD common_source/floor.c:
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)floor.c	5.7 (Berkeley) 10/9/90";
+#endif /* not lint */
+
+#include "mathimpl.h"
+
+vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
+
+ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */
+
+#ifdef vccast
+#define	L	vccast(L)
+#endif
+
+double
+ceil(x)
+double x;
+{
+	double y;
+
+	if (
+#if !defined(vax)&&!defined(tahoe)
+		x != x ||	/* NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+		x >= L)		/* already an even integer */
+		return x;
+	else if (x < (double)0)
+		return -floor(-x);
+	else {			/* now 0 <= x < L */
+		y = L+x;		/* destructive store must be forced */
+		y -= L;			/* an integer, and |x-y| < 1 */
+		return x > y ? y+(double)1 : y;
+	}
+}
+
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/cmp.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/cmp.c
@@ -0,0 +1,55 @@
+/* __mpn_cmp -- Compare two low-level natural-number integers.
+
+Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
+   There are no restrictions on the relative sizes of
+   the two arguments.
+   Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2.  */
+
+int
+#if __STDC__
+__mpn_cmp (mp_srcptr op1_ptr, mp_srcptr op2_ptr, mp_size_t size)
+#else
+__mpn_cmp (op1_ptr, op2_ptr, size)
+     mp_srcptr op1_ptr;
+     mp_srcptr op2_ptr;
+     mp_size_t size;
+#endif
+{
+  mp_size_t i;
+  mp_limb op1_word, op2_word;
+
+  for (i = size - 1; i >= 0; i--)
+    {
+      op1_word = op1_ptr[i];
+      op2_word = op2_ptr[i];
+      if (op1_word != op2_word)
+	goto diff;
+    }
+  return 0;
+ diff:
+  /* This can *not* be simplified to
+	op2_word - op2_word
+     since that expression might give signed overflow.  */
+  return (op1_word > op2_word) ? 1 : -1;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/cosh.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/cosh.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cosh.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* COSH(X)
+ * RETURN THE HYPERBOLIC COSINE OF X
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85; 
+ * REVISED BY K.C. NG on 2/8/85, 2/23/85, 3/7/85, 3/29/85, 4/16/85.
+ *
+ * Required system supported functions :
+ *	copysign(x,y)
+ *	scalb(x,N)
+ *
+ * Required kernel function:
+ *	exp(x) 
+ *	exp__E(x,c)	...return exp(x+c)-1-x for |x|<0.3465
+ *
+ * Method :
+ *	1. Replace x by |x|. 
+ *	2. 
+ *		                                        [ exp(x) - 1 ]^2 
+ *	    0        <= x <= 0.3465  :  cosh(x) := 1 + -------------------
+ *			       			           2*exp(x)
+ *
+ *		                                   exp(x) +  1/exp(x)
+ *	    0.3465   <= x <= 22      :  cosh(x) := -------------------
+ *			       			           2
+ *	    22       <= x <= lnovfl  :  cosh(x) := exp(x)/2 
+ *	    lnovfl   <= x <= lnovfl+log(2)
+ *				     :  cosh(x) := exp(x)/2 (avoid overflow)
+ *	    log(2)+lnovfl <  x <  INF:  overflow to INF
+ *
+ *	Note: .3465 is a number near one half of ln2.
+ *
+ * Special cases:
+ *	cosh(x) is x if x is +INF, -INF, or NaN.
+ *	only cosh(0)=1 is exact for finite x.
+ *
+ * Accuracy:
+ *	cosh(x) returns the exact hyperbolic cosine of x nearly rounded.
+ *	In a test run with 768,000 random arguments on a VAX, the maximum
+ *	observed error was 1.23 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(mln2hi, 8.8029691931113054792E1   ,0f33,43b0,2bdb,c7e2,   7, .B00F33C7E22BDB)
+vc(mln2lo,-4.9650192275318476525E-16 ,1b60,a70f,582a,279e, -50,-.8F1B60279E582A)
+vc(lnovfl, 8.8029691931113053016E1   ,0f33,43b0,2bda,c7e2,   7, .B00F33C7E22BDA)
+
+ic(mln2hi, 7.0978271289338397310E2,    10, 1.62E42FEFA39EF)
+ic(mln2lo, 2.3747039373786107478E-14, -45, 1.ABC9E3B39803F)
+ic(lnovfl, 7.0978271289338397310E2,     9, 1.62E42FEFA39EF)
+
+#ifdef vccast
+#define   mln2hi    vccast(mln2hi)
+#define   mln2lo    vccast(mln2lo)
+#define   lnovfl    vccast(lnovfl)
+#endif
+
+#if defined(vax)||defined(tahoe)
+static max = 126                      ;
+#else	/* defined(vax)||defined(tahoe) */
+static max = 1023                     ;
+#endif	/* defined(vax)||defined(tahoe) */
+
+extern double scalb();
+
+double cosh(x)
+double x;
+{	
+	static const double half=1.0/2.0,
+		one=1.0, small=1.0E-18; /* fl(1+small)==1 */
+	double t;
+
+#if !defined(vax)&&!defined(tahoe)
+	if(x!=x) return(x);	/* x is NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+	if((x=copysign(x,one)) <= 22)
+	    if(x<0.3465) 
+		if(x<small) return(one+x);
+		else {t=x+__exp__E(x,0.0);x=t+t; return(one+t*t/(2.0+x)); }
+
+	    else /* for x lies in [0.3465,22] */
+	        { t=exp(x); return((t+one/t)*half); }
+
+	if( lnovfl <= x && x <= (lnovfl+0.7)) 
+        /* for x lies in [lnovfl, lnovfl+ln2], decrease x by ln(2^(max+1)) 
+         * and return 2^max*exp(x) to avoid unnecessary overflow 
+         */
+	    return(scalb(exp((x-mln2hi)-mln2lo), max)); 
+
+	else 
+	    return(exp(x)*half);	/* for large x,  cosh(x)=exp(x)/2 */
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/drem.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/drem.c
@@ -0,0 +1,109 @@
+/* Copyright (C) 1992, 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/*
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted provided
+ * that: (1) source distributions retain this entire copyright notice and
+ * comment, and (2) distributions including binaries display the following
+ * acknowledgement:  ``This product includes software developed by the
+ * University of California, Berkeley and its contributors'' in the
+ * documentation or other materials provided with the distribution and in
+ * all advertising materials mentioning features or use of this software.
+ * Neither the name of the University nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <ansidecl.h>
+#include <math.h>
+#include <float.h>
+#include "ieee754.h"
+
+extern double EXFUN(__scalb, (double x, double y));
+
+/* Return the remainder of X/Y.  */
+double
+DEFUN(__drem, (x, y),
+      double x AND double y)
+{
+  union ieee754_double ux, uy;
+
+  ux.d = x;
+  uy.d = y;
+#define x ux.d
+#define	y uy.d
+
+  uy.ieee.negative = 0;
+
+  if (!__finite (x) || y == 0.0)
+    return NAN;
+  else if (__isnan (y))
+    return y;
+  else if (__isinf (y))
+    return x;
+  else if (uy.ieee.exponent <= 1)
+    {
+      /* Subnormal (or almost subnormal) Y value.  */
+      double b = __scalb (1.0, 54);
+      y *= b;
+      x = __drem (x, y);
+      x *= b;
+      return __drem (x, y) / b;
+    }
+  else if (y >= 1.7e308 / 2)
+    {
+      y /= 2;
+      x /= 2;
+      return __drem (x, y) * 2;
+    }
+  else
+    {
+      union ieee754_double a;
+      double b;
+      unsigned int negative = ux.ieee.negative;
+      a.d = y + y;
+      b = y / 2;
+      ux.ieee.negative = 0;
+      while (x > a.d)
+	{
+	  unsigned short int k = ux.ieee.exponent - a.ieee.exponent;
+	  union ieee754_double tmp;
+	  tmp.d = a.d;
+	  tmp.ieee.exponent += k;
+	  if (x < tmp.d)
+	    --tmp.ieee.exponent;
+	  x -= tmp.d;
+	}
+      if (x > b)
+	{
+	  x -= y;
+	  if (x >= b)
+	    x -= y;
+	}
+      ux.ieee.negative ^= negative;
+      return x;
+    }
+}
+
+/* weak_alias (__drem, drem) */
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/erf.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/erf.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)erf.c	5.2 (Berkeley) 4/29/88";
+#endif /* not lint */
+#endif
+
+/*
+	C program for floating point error function
+
+	erf(x) returns the error function of its argument
+	erfc(x) returns 1.0-erf(x)
+
+	erf(x) is defined by
+	${2 over sqrt(pi)} int from 0 to x e sup {-t sup 2} dt$
+
+	the entry for erfc is provided because of the
+	extreme loss of relative accuracy if erf(x) is
+	called for large x and the result subtracted
+	from 1. (e.g. for x= 10, 12 places are lost).
+
+	There are no error returns.
+
+	Calls exp.
+
+	Coefficients for large x are #5667 from Hart & Cheney (18.72D).
+*/
+
+#include <math.h>
+
+#define M 7
+#define N 9
+static double torp = 1.1283791670955125738961589031;
+static double p1[] = {
+	0.804373630960840172832162e5,
+	0.740407142710151470082064e4,
+	0.301782788536507577809226e4,
+	0.380140318123903008244444e2,
+	0.143383842191748205576712e2,
+	-.288805137207594084924010e0,
+	0.007547728033418631287834e0,
+};
+static double q1[]  = {
+	0.804373630960840172826266e5,
+	0.342165257924628539769006e5,
+	0.637960017324428279487120e4,
+	0.658070155459240506326937e3,
+	0.380190713951939403753468e2,
+	0.100000000000000000000000e1,
+	0.0,
+};
+static double p2[]  = {
+	0.18263348842295112592168999e4,
+	0.28980293292167655611275846e4,
+	0.2320439590251635247384768711e4,
+	0.1143262070703886173606073338e4,
+	0.3685196154710010637133875746e3,
+	0.7708161730368428609781633646e2,
+	0.9675807882987265400604202961e1,
+	0.5641877825507397413087057563e0,
+	0.0,
+};
+static double q2[]  = {
+	0.18263348842295112595576438e4,
+	0.495882756472114071495438422e4,
+	0.60895424232724435504633068e4,
+	0.4429612803883682726711528526e4,
+	0.2094384367789539593790281779e4,
+	0.6617361207107653469211984771e3,
+	0.1371255960500622202878443578e3,
+	0.1714980943627607849376131193e2,
+	1.0,
+};
+
+double
+erf(double arg)
+{
+	int sign;
+	double argsq;
+	double d, n;
+	int i;
+
+	sign = 1;
+	if(arg < 0.){
+		arg = -arg;
+		sign = -1;
+	}
+	if(arg < 0.5){
+		argsq = arg*arg;
+		for(n=0,d=0,i=M-1; i>=0; i--){
+			n = n*argsq + p1[i];
+			d = d*argsq + q1[i];
+		}
+		return(sign*torp*arg*n/d);
+	}
+	if(arg >= 10.)
+		return(sign*1.);
+	return(sign*(1. - erfc(arg)));
+}
+
+double
+erfc(double arg)
+{
+	double n, d;
+	int i;
+
+	if(arg < 0.)
+		return(2. - erfc(-arg));
+/*
+	if(arg < 0.5)
+		return(1. - erf(arg));
+*/
+	if(arg >= 10.)
+		return(0.);
+
+	for(n=0,d=0,i=N-1; i>=0; i--){
+		n = n*arg + p2[i];
+		d = d*arg + q2[i];
+	}
+	return(exp(-arg*arg)*n/d);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/j0.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/j0.c
@@ -0,0 +1,182 @@
+#include <math.h>
+
+/*
+	floating point Bessel's function
+	of the first and second kinds
+	of order zero
+
+	j0(x) returns the value of J0(x)
+	for all real values of x.
+
+	There are no error returns.
+	Calls sin, cos, sqrt.
+
+	There is a niggling bug in J0 which
+	causes errors up to 2e-16 for x in the
+	interval [-8,8].
+	The bug is caused by an inappropriate order
+	of summation of the series.  rhm will fix it
+	someday.
+
+	Coefficients are from Hart & Cheney.
+	#5849 (19.22D)
+	#6549 (19.25D)
+	#6949 (19.41D)
+
+	y0(x) returns the value of Y0(x)
+	for positive real values of x.
+	For x<=0, error number EDOM is set and a
+	large negative value is returned.
+
+	Calls sin, cos, sqrt, log, j0.
+
+	The values of Y0 have not been checked
+	to more than ten places.
+
+	Coefficients are from Hart & Cheney.
+	#6245 (18.78D)
+	#6549 (19.25D)
+	#6949 (19.41D)
+*/
+
+static void asympt(double);
+static double pzero, qzero;
+static double tpi	= .6366197723675813430755350535e0;
+static double pio4	= .7853981633974483096156608458e0;
+static double p1[] = {
+	0.4933787251794133561816813446e21,
+	-.1179157629107610536038440800e21,
+	0.6382059341072356562289432465e19,
+	-.1367620353088171386865416609e18,
+	0.1434354939140344111664316553e16,
+	-.8085222034853793871199468171e13,
+	0.2507158285536881945555156435e11,
+	-.4050412371833132706360663322e8,
+	0.2685786856980014981415848441e5,
+};
+static double q1[] = {
+	0.4933787251794133562113278438e21,
+	0.5428918384092285160200195092e19,
+	0.3024635616709462698627330784e17,
+	0.1127756739679798507056031594e15,
+	0.3123043114941213172572469442e12,
+	0.6699987672982239671814028660e9,
+	0.1114636098462985378182402543e7,
+	0.1363063652328970604442810507e4,
+	1.0
+};
+static double p2[] = {
+	0.5393485083869438325262122897e7,
+	0.1233238476817638145232406055e8,
+	0.8413041456550439208464315611e7,
+	0.2016135283049983642487182349e7,
+	0.1539826532623911470917825993e6,
+	0.2485271928957404011288128951e4,
+	0.0,
+};
+static double q2[] = {
+	0.5393485083869438325560444960e7,
+	0.1233831022786324960844856182e8,
+	0.8426449050629797331554404810e7,
+	0.2025066801570134013891035236e7,
+	0.1560017276940030940592769933e6,
+	0.2615700736920839685159081813e4,
+	1.0,
+};
+static double p3[] = {
+	-.3984617357595222463506790588e4,
+	-.1038141698748464093880530341e5,
+	-.8239066313485606568803548860e4,
+	-.2365956170779108192723612816e4,
+	-.2262630641933704113967255053e3,
+	-.4887199395841261531199129300e1,
+	0.0,
+};
+static double q3[] = {
+	0.2550155108860942382983170882e6,
+	0.6667454239319826986004038103e6,
+	0.5332913634216897168722255057e6,
+	0.1560213206679291652539287109e6,
+	0.1570489191515395519392882766e5,
+	0.4087714673983499223402830260e3,
+	1.0,
+};
+static double p4[] = {
+	-.2750286678629109583701933175e20,
+	0.6587473275719554925999402049e20,
+	-.5247065581112764941297350814e19,
+	0.1375624316399344078571335453e18,
+	-.1648605817185729473122082537e16,
+	0.1025520859686394284509167421e14,
+	-.3436371222979040378171030138e11,
+	0.5915213465686889654273830069e8,
+	-.4137035497933148554125235152e5,
+};
+static double q4[] = {
+	0.3726458838986165881989980e21,
+	0.4192417043410839973904769661e19,
+	0.2392883043499781857439356652e17,
+	0.9162038034075185262489147968e14,
+	0.2613065755041081249568482092e12,
+	0.5795122640700729537480087915e9,
+	0.1001702641288906265666651753e7,
+	0.1282452772478993804176329391e4,
+	1.0,
+};
+
+double j0(double arg)
+{
+	double argsq, n, d;
+	int i;
+
+	if(arg < 0.) arg = -arg;
+	if(arg > 8.){
+		asympt(arg);
+		n = arg - pio4;
+		return(sqrt(tpi/arg)*(pzero*cos(n) - qzero*sin(n)));
+	}
+	argsq = arg*arg;
+	for(n=0,d=0,i=8;i>=0;i--){
+		n = n*argsq + p1[i];
+		d = d*argsq + q1[i];
+	}
+	return(n/d);
+}
+
+double y0(double arg)
+{
+	double argsq, n, d;
+	int i;
+
+	if(arg <= 0.){
+		return(-HUGE_VAL);
+	}
+	if(arg > 8.){
+		asympt(arg);
+		n = arg - pio4;
+		return(sqrt(tpi/arg)*(pzero*sin(n) + qzero*cos(n)));
+	}
+	argsq = arg*arg;
+	for(n=0,d=0,i=8;i>=0;i--){
+		n = n*argsq + p4[i];
+		d = d*argsq + q4[i];
+	}
+	return(n/d + tpi*j0(arg)*log(arg));
+}
+
+static void asympt(double arg)
+{
+	double zsq, n, d;
+	int i;
+	zsq = 64./(arg*arg);
+	for(n=0,d=0,i=6;i>=0;i--){
+		n = n*zsq + p2[i];
+		d = d*zsq + q2[i];
+	}
+	pzero = n/d;
+	for(n=0,d=0,i=6;i>=0;i--){
+		n = n*zsq + p3[i];
+		d = d*zsq + q3[i];
+	}
+	qzero = (8./arg)*(n/d);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/erfl.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/erfl.c
@@ -0,0 +1,325 @@
+/*							erf.c
+ *
+ *	Error function
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double x, y, erf();
+ *
+ * y = erf( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * The integral is
+ *
+ *                           x 
+ *                            -
+ *                 2         | |          2
+ *   erf(x)  =  --------     |    exp( - t  ) dt.
+ *              sqrt(pi)   | |
+ *                          -
+ *                           0
+ *
+ * The magnitude of x is limited to 9.231948545 for DEC
+ * arithmetic; 1 or -1 is returned outside this range.
+ *
+ * For 0 <= |x| < 1, erf(x) = x * P6(x^2)/Q6(x^2); otherwise
+ * erf(x) = 1 - erfc(x).
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      0,1          3000       1.8e-19     6.5e-20
+ *
+ */
+/*							erfc.c
+ *
+ *	Complementary error function
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double x, y, erfc();
+ *
+ * y = erfc( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ *
+ *  1 - erf(x) =
+ *
+ *                           inf. 
+ *                             -
+ *                  2         | |          2
+ *   erfc(x)  =  --------     |    exp( - t  ) dt
+ *               sqrt(pi)   | |
+ *                           -
+ *                            x
+ *
+ *
+ * For small x, erfc(x) = 1 - erf(x); otherwise rational
+ * approximations are computed.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      0,8         1000       1.8e-18     6.1e-19
+ * For x > 1, error is dominated by the calculation of exp(-x^2)
+ * and is of order 3e-19 x.
+ *
+ *
+ * ERROR MESSAGES:
+ *
+ *   message         condition              value returned
+ * erfc underflow    x > sqrt(MAXLOGL)          0.0
+ *
+ *
+ */
+
+/*							ndtr.c
+ *
+ *	Normal distribution function
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double x, y, ndtr();
+ *
+ * y = ndtr( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the area under the Gaussian probability density
+ * function, integrated from minus infinity to x:
+ *
+ *                            x
+ *                             -
+ *                   1        | |          2
+ *    ndtr(x)  = ---------    |    exp( - t /2 ) dt
+ *               sqrt(2pi)  | |
+ *                           -
+ *                          -inf.
+ *
+ *             =  ( 1 + erf(z) ) / 2
+ *             =  erfc(z) / 2
+ *
+ * where z = x/sqrt(2). Computation is via the functions
+ * erf and erfc.
+ *
+ *
+ * ACCURACY:
+ *
+ * See erfl, erfc.
+ *
+ * ERROR MESSAGES:
+ *
+ *   message         condition         value returned
+ * erfc underflow    x > sqrt(MAXLOGL)      0.0
+ *
+ */
+
+/*
+Cephes Math Library Release 2.2:  June, 1992
+Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
+Direct inquiries to 30 Frost Street, Cambridge, MA 02140
+*/
+
+#include "mathl.h"
+extern long double __polevll ( long double, long double *, int );
+extern long double __p1evll ( long double, long double *, int );
+
+#define SQRTH 7.07106781186547524401E-1L
+#define MAXLOGL 1.1356523406294143949492E4L
+
+/*
+erfc(x) = exp(-x^2) P(z)/Q(z)
+z(x) = 1/x
+Relative error
+n=9, d=10
+Peak error =  7.761600916141239627567679213879910992123E-21
+Relative error spread =  1.023351469044268241908780645010281568783E0
+*/
+static long double P[] = {
+ 1.257754157740948157833312785512722262237E9L,
+ 2.544170037359209505076053758183547658874E9L,
+ 2.546959074195068787444430942851029462365E9L,
+ 1.605230257662887752768505542850382838437E9L,
+ 6.899137924684927504585242368865475647796E8L,
+ 2.066152777382002343549858319788089708173E8L,
+ 4.227432144169649646138430076248102333111E7L,
+ 5.463192951525719736944609969792412137906E6L,
+ 3.509752864577976833796176700600960407890E5L,
+-1.071020848327048365754654097516174838747E-5L,
+};
+static long double Q[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+ 1.257754146471137811029618866219716318753E9L,
+ 3.963393686787501126271033323119385984564E9L,
+ 5.761415509088700168863599482318704228527E9L,
+ 5.089047658881201390929483867868625212361E9L,
+ 3.023468726254039362316680583964735625632E9L,
+ 1.259993446190802606495833425577455019099E9L,
+ 3.710577088683661371497272954319350172686E8L,
+ 7.524032571027728454099705963391636990057E7L,
+ 9.683257455518460133999913804480458079007E6L,
+ 6.220874963793103874137444426727337364012E5L
+};
+/*
+erfc(x) = exp(-x^2) z P(z**2)/Q(z**2)
+z(x) = 1/x
+x >= 8
+Relative error
+n=4, d=5
+Peak error =  1.82e-21
+Relative error spread =  3.9e-3
+*/
+static long double R[] = {
+ 3.621771504143418323727691824727645990561E0L,
+ 7.176028075353789451273277986715563076155E0L,
+ 3.446811092743012309113505238337669421091E0L,
+ 5.541324340261065929875426053951866015250E-1L,
+ 2.699905677541423267238580904507582955709E-2L
+};
+static long double S[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+ 1.073074561751358600517229966140297947840E1L,
+ 1.534256653809200505130664147433856235472E1L,
+ 6.576473386900615376978244623190582091578E0L,
+ 1.006101457677419240008726711451145446254E0L,
+ 4.785458215239962067727484634993830260306E-2L
+};
+/*
+erf(x)  z P(z**2)/Q(z**2)
+0 <= x <= 1
+z(x) = x
+Relative error
+n=6, d=6
+Peak error =  7.640688643888757419028899590163681314010E-23
+Relative error spread =  9.108314657350825251106158661154911170107E-3
+*/
+static long double T[] = {
+ 1.097461701666048418572764102524978668857E-1L,
+ 5.403114568277600506272199159607654730741E0L,
+ 2.871755797503643801098000314688440010017E2L,
+ 2.677455035557940040284806618777105723130E3L,
+ 4.825836895686958085365801683371047641820E4L,
+ 1.549871261553367266536226453640515782388E5L,
+ 1.104347959782514112319886330985904796384E6L
+};
+static long double U[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+ 4.525736349514749653000420739995094197946E1L,
+ 9.715176200212976593594958594375455394272E2L,
+ 1.245878656969449881132817817129763145725E4L,
+ 9.942693068079099139656602031366763195331E4L,
+ 4.635880633067639826809494193933792409347E5L,
+ 9.787028970280835391789815008496258590638E5L
+};
+
+#define UTHRESH 37.519379347
+
+/*
+double ndtr(a)
+double a;
+{
+double x, y, z;
+double fabs(), erf(), erfc();
+
+x = a * SQRTH;
+z = fabs(x);
+
+if( z < SQRTH )
+	y = 0.5 + 0.5 * erf(x);
+
+else
+	{
+	y = 0.5 * erfc(z);
+
+	if( x > 0 )
+		y = 1.0 - y;
+	}
+
+return(y);
+}
+*/
+
+long double erfcl(long double a)
+{
+long double p,q,x,y,z;
+
+
+if( a < 0.0L )
+	x = -a;
+else
+	x = a;
+
+if( x < 1.0L )
+	return( 1.0L - erfl(a) );
+
+z = -a * a;
+
+if( z < -MAXLOGL )
+	{
+under:
+/* Some kind of error flagging needed. */
+/*	mtherr( "erfcl", UNDERFLOW ); */
+	if( a < 0 )
+		return( 2.0L );
+	else
+		return( 0.0L );
+	}
+
+z = expl(z);
+
+if( x < 8.0L )
+	{
+	  y = 1.0/a;
+	p = __polevll( y, P, 9 );
+	q = __p1evll( y, Q, 10 );
+	}
+else
+	{
+	y = 1.0/(a*a);
+	p = __polevll( y, R, 4 ) / a;
+	q = __p1evll( y, S, 5 );
+	}
+y = (z * p)/q;
+
+if( a < 0 )
+	y = 2.0L - y;
+
+if( y == 0.0L )
+	goto under;
+
+return(y);
+}
+
+
+
+long double erfl(long double x)
+{
+long double y, z;
+
+if( fabsl(x) > 1.0L )
+	return( 1.0L - erfcl(x) );
+
+z = x * x;
+y = x * __polevll( z, T, 6 ) / __p1evll( z, U, 6 );
+return( y );
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/exp.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/exp.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)exp.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* EXP(X)
+ * RETURN THE EXPONENTIAL OF X
+ * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85; 
+ * REVISED BY K.C. NG on 2/6/85, 2/15/85, 3/7/85, 3/24/85, 4/16/85, 6/14/86.
+ *
+ * Required system supported functions:
+ *	scalb(x,n)	
+ *	copysign(x,y)	
+ *	finite(x)
+ *
+ * Method:
+ *	1. Argument Reduction: given the input x, find r and integer k such 
+ *	   that
+ *	                   x = k*ln2 + r,  |r| <= 0.5*ln2 .  
+ *	   r will be represented as r := z+c for better accuracy.
+ *
+ *	2. Compute exp(r) by 
+ *
+ *		exp(r) = 1 + r + r*R1/(2-R1),
+ *	   where
+ *		R1 = x - x^2*(p1+x^2*(p2+x^2*(p3+x^2*(p4+p5*x^2)))).
+ *
+ *	3. exp(x) = 2^k * exp(r) .
+ *
+ * Special cases:
+ *	exp(INF) is INF, exp(NaN) is NaN;
+ *	exp(-INF)=  0;
+ *	for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ *	exp(x) returns the exponential of x nearly rounded. In a test run
+ *	with 1,156,000 random arguments on a VAX, the maximum observed
+ *	error was 0.869 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi,  6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000)
+vc(ln2lo,  1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(lnhuge, 9.4961163736712506989E1   ,ec1d,43bd,9010,a73e,   7, .BDEC1DA73E9010)
+vc(lntiny,-9.5654310917272452386E1   ,4f01,c3bf,33af,d72e,   7,-.BF4F01D72E33AF)
+vc(invln2, 1.4426950408889634148E0   ,aa3b,40b8,17f1,295c,   1, .B8AA3B295C17F1)
+vc(p1,     1.6666666666666602251E-1  ,aaaa,3f2a,a9f1,aaaa,  -2, .AAAAAAAAAAA9F1)
+vc(p2,    -2.7777777777015591216E-3  ,0b60,bc36,ec94,b5f5,  -8,-.B60B60B5F5EC94)
+vc(p3,     6.6137563214379341918E-5  ,b355,398a,f15f,792e, -13, .8AB355792EF15F)
+vc(p4,    -1.6533902205465250480E-6  ,ea0e,b6dd,5f84,2e93, -19,-.DDEA0E2E935F84)
+vc(p5,     4.1381367970572387085E-8  ,bb4b,3431,2683,95f5, -24, .B1BB4B95F52683)
+
+#ifdef vccast
+#define    ln2hi    vccast(ln2hi)
+#define    ln2lo    vccast(ln2lo)
+#define   lnhuge    vccast(lnhuge)
+#define   lntiny    vccast(lntiny)
+#define   invln2    vccast(invln2)
+#define       p1    vccast(p1)
+#define       p2    vccast(p2)
+#define       p3    vccast(p3)
+#define       p4    vccast(p4)
+#define       p5    vccast(p5)
+#endif
+
+ic(p1,     1.6666666666666601904E-1,  -3,  1.555555555553E)
+ic(p2,    -2.7777777777015593384E-3,  -9, -1.6C16C16BEBD93)
+ic(p3,     6.6137563214379343612E-5, -14,  1.1566AAF25DE2C)
+ic(p4,    -1.6533902205465251539E-6, -20, -1.BBD41C5D26BF1)
+ic(p5,     4.1381367970572384604E-8, -25,  1.6376972BEA4D0)
+ic(ln2hi,  6.9314718036912381649E-1,  -1,  1.62E42FEE00000)
+ic(ln2lo,  1.9082149292705877000E-10,-33,  1.A39EF35793C76)
+ic(lnhuge, 7.1602103751842355450E2,    9,  1.6602B15B7ECF2)
+ic(lntiny,-7.5137154372698068983E2,    9, -1.77AF8EBEAE354)
+ic(invln2, 1.4426950408889633870E0,    0,  1.71547652B82FE)
+
+extern double scalb();
+
+double exp(x)
+double x;
+{
+	double  z,hi,lo,c;
+	int k;
+
+#if !defined(vax)&&!defined(tahoe)
+	if(x!=x) return(x);	/* x is NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+	if( x <= lnhuge ) {
+		if( x >= lntiny ) {
+
+		    /* argument reduction : x --> x - k*ln2 */
+
+			k=invln2*x+copysign(0.5,x);	/* k=NINT(x/ln2) */
+
+		    /* express x-k*ln2 as hi-lo and let x=hi-lo rounded */
+
+			hi=x-k*ln2hi;
+			x=hi-(lo=k*ln2lo);
+
+		    /* return 2^k*[1+x+x*c/(2+c)]  */
+			z=x*x;
+			c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
+			return  scalb(1.0+(hi-(lo-(x*c)/(2.0-c))),k);
+
+		}
+		/* end of x > lntiny */
+
+		else 
+		     /* exp(-big#) underflows to zero */
+		     if(finite(x))  return(scalb(1.0,-5000));
+
+		     /* exp(-INF) is zero */
+		     else return(0.0);
+	}
+	/* end of x < lnhuge */
+
+	else 
+	/* exp(INF) is INF, exp(+big#) overflows to INF */
+	    return( finite(x) ?  scalb(1.0,5000)  : x);
+}
+
+/* returns exp(r = x + c) for |c| < |x| with no overlap.  */
+
+double __exp__D(x, c)
+double x, c;
+{
+	double  z,hi,lo, t;
+	int k;
+
+#if !defined(vax)&&!defined(tahoe)
+	if (x!=x) return(x);	/* x is NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+	if ( x <= lnhuge ) {
+		if ( x >= lntiny ) {
+
+		    /* argument reduction : x --> x - k*ln2 */
+			z = invln2*x;
+			k = z + copysign(.5, x);
+
+		    /* express (x+c)-k*ln2 as hi-lo and let x=hi-lo rounded */
+
+			hi=(x-k*ln2hi);			/* Exact. */
+			x= hi - (lo = k*ln2lo-c);
+		    /* return 2^k*[1+x+x*c/(2+c)]  */
+			z=x*x;
+			c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
+			c = (x*c)/(2.0-c);
+
+			return  scalb(1.+(hi-(lo - c)), k);
+		}
+		/* end of x > lntiny */
+
+		else 
+		     /* exp(-big#) underflows to zero */
+		     if(finite(x))  return(scalb(1.0,-5000));
+
+		     /* exp(-INF) is zero */
+		     else return(0.0);
+	}
+	/* end of x < lnhuge */
+
+	else 
+	/* exp(INF) is INF, exp(+big#) overflows to INF */
+	    return( finite(x) ?  scalb(1.0,5000)  : x);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/exp__E.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/exp__E.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)exp__E.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* exp__E(x,c)
+ * ASSUMPTION: c << x  SO THAT  fl(x+c)=x.
+ * (c is the correction term for x)
+ * exp__E RETURNS
+ *
+ *			 /  exp(x+c) - 1 - x ,  1E-19 < |x| < .3465736
+ *       exp__E(x,c) = 	| 		     
+ *			 \  0 ,  |x| < 1E-19.
+ *
+ * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS)
+ * KERNEL FUNCTION OF EXP, EXPM1, POW FUNCTIONS
+ * CODED IN C BY K.C. NG, 1/31/85;
+ * REVISED BY K.C. NG on 3/16/85, 4/16/85.
+ *
+ * Required system supported function:
+ *	copysign(x,y)	
+ *
+ * Method:
+ *	1. Rational approximation. Let r=x+c.
+ *	   Based on
+ *                                   2 * sinh(r/2)     
+ *                exp(r) - 1 =   ----------------------   ,
+ *                               cosh(r/2) - sinh(r/2)
+ *	   exp__E(r) is computed using
+ *                   x*x            (x/2)*W - ( Q - ( 2*P  + x*P ) )
+ *                   --- + (c + x*[---------------------------------- + c ])
+ *                    2                          1 - W
+ * 	   where  P := p1*x^2 + p2*x^4,
+ *	          Q := q1*x^2 + q2*x^4 (for 56 bits precision, add q3*x^6)
+ *	          W := x/2-(Q-x*P),
+ *
+ *	   (See the listing below for the values of p1,p2,q1,q2,q3. The poly-
+ *	    nomials P and Q may be regarded as the approximations to sinh
+ *	    and cosh :
+ *		sinh(r/2) =  r/2 + r * P  ,  cosh(r/2) =  1 + Q . )
+ *
+ *         The coefficients were obtained by a special Remez algorithm.
+ *
+ * Approximation error:
+ *
+ *   |	exp(x) - 1			   |        2**(-57),  (IEEE double)
+ *   | ------------  -  (exp__E(x,0)+x)/x  |  <= 
+ *   |	     x			           |	    2**(-69).  (VAX D)
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(p1, 1.5150724356786683059E-2 ,3abe,3d78,066a,67e1,  -6, .F83ABE67E1066A)
+vc(p2, 6.3112487873718332688E-5 ,5b42,3984,0173,48cd, -13, .845B4248CD0173)
+vc(q1, 1.1363478204690669916E-1 ,b95a,3ee8,ec45,44a2,  -3, .E8B95A44A2EC45)
+vc(q2, 1.2624568129896839182E-3 ,7905,3ba5,f5e7,72e4,  -9, .A5790572E4F5E7)
+vc(q3, 1.5021856115869022674E-6 ,9eb4,36c9,c395,604a, -19, .C99EB4604AC395)
+
+ic(p1, 1.3887401997267371720E-2,  -7, 1.C70FF8B3CC2CF)
+ic(p2, 3.3044019718331897649E-5, -15, 1.15317DF4526C4)
+ic(q1, 1.1110813732786649355E-1,  -4, 1.C719538248597)
+ic(q2, 9.9176615021572857300E-4, -10, 1.03FC4CB8C98E8)
+
+#ifdef vccast
+#define       p1    vccast(p1)
+#define       p2    vccast(p2)
+#define       q1    vccast(q1)
+#define       q2    vccast(q2)
+#define       q3    vccast(q3)
+#endif
+
+double __exp__E(x,c)
+double x,c;
+{
+	const static double zero=0.0, one=1.0, half=1.0/2.0, small=1.0E-19;
+	double z,p,q,xp,xh,w;
+	if(copysign(x,one)>small) {
+           z = x*x  ;
+	   p = z*( p1 +z* p2 );
+#if defined(vax)||defined(tahoe)
+           q = z*( q1 +z*( q2 +z* q3 ));
+#else	/* defined(vax)||defined(tahoe) */
+           q = z*( q1 +z*  q2 );
+#endif	/* defined(vax)||defined(tahoe) */
+           xp= x*p     ; 
+	   xh= x*half  ;
+           w = xh-(q-xp)  ;
+	   p = p+p;
+	   c += x*((xh*w-(q-(p+xp)))/(one-w)+c);
+	   return(z*half+c);
+	}
+	/* end of |x| > small */
+
+	else {
+	    if(x!=zero) one+small;	/* raise the inexact flag */
+	    return(copysign(zero,x));
+	}
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/fabs.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/fabs.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <math.h>
+
+/* Return the absolute value of X.  */
+double
+DEFUN(fabs, (x), register double x)
+{
+  return x < 0.0 ? -x : x;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/ffs.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/ffs.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <limits.h>
+#include <string.h>
+
+#undef	ffs
+
+
+/* Find the first bit set in I.  */
+int
+DEFUN(ffs, (i), int i)
+{
+  static CONST unsigned char table[] =
+    {
+      0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+      6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+      7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+      7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+    };
+  unsigned long int a;
+  unsigned long int x = i & -i;
+
+  a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ?  16 : 24);
+
+  return table[x >> a] + a;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/floor.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/floor.c
@@ -0,0 +1,74 @@
+/* snarfed from BSD common_source/floor.c:
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)floor.c	5.7 (Berkeley) 10/9/90";
+#endif /* not lint */
+
+#include "mathimpl.h"
+
+vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
+
+ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */
+
+#ifdef vccast
+#define	L	vccast(L)
+#endif
+
+/*
+ * floor(x) := the largest integer no larger than x;
+ * ceil(x) := -floor(-x), for all real x.
+ *
+ * Note: Inexact will be signaled if x is not an integer, as is
+ *	customary for IEEE 754.  No other signal can be emitted.
+ */
+double
+floor(x)
+double x;
+{
+	double y;
+
+	if (
+#if !defined(vax)&&!defined(tahoe)
+		x != x ||	/* NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+		x >= L)		/* already an even integer */
+		return x;
+	else if (x < (double)0)
+		return -ceil(-x);
+	else {			/* now 0 <= x < L */
+		y = L+x;		/* destructive store must be forced */
+		y -= L;			/* an integer, and |x-y| < 1 */
+		return x < y ? y-(double)1 : y;
+	}
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/fmod.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/fmod.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)fmod.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* fmod.c
+ *
+ * SYNOPSIS
+ *
+ *    #include <math.h>
+ *    double fmod(double x, double y)
+ *
+ * DESCRIPTION
+ *
+ *    The fmod function computes the floating-point remainder of x/y.
+ *
+ * RETURNS
+ *
+ *    The fmod function returns the value x-i*y, for some integer i
+ * such that, if y is nonzero, the result has the same sign as x and
+ * magnitude less than the magnitude of y.
+ *
+ * On a VAX or CCI,
+ *
+ *    fmod(x,0) traps/faults on floating-point divided-by-zero.
+ *
+ * On IEEE-754 conforming machines with "isnan()" primitive,
+ *
+ *    fmod(x,0), fmod(INF,y) are invalid operations and NaN is returned.
+ *
+ */
+#if !defined(vax) && !defined(tahoe)
+extern int isnan(),finite();
+#endif	/* !defined(vax) && !defined(tahoe) */
+extern double frexp(),ldexp(),fabs();
+
+#ifdef TEST_FMOD
+static double
+_fmod(x,y)
+#else	/* TEST_FMOD */
+double
+fmod(x,y)
+#endif	/* TEST_FMOD */
+double x,y;
+{
+	int ir,iy;
+	double r,w;
+
+	if (y == (double)0
+#if !defined(vax) && !defined(tahoe)	/* per "fmod" manual entry, SunOS 4.0 */
+		|| isnan(y) || !finite(x)
+#endif	/* !defined(vax) && !defined(tahoe) */
+	    )
+	    return (x*y)/(x*y);
+
+	r = fabs(x);
+	y = fabs(y);
+	(void)frexp(y,&iy);
+	while (r >= y) {
+		(void)frexp(r,&ir);
+		w = ldexp(y,ir-iy);
+		r -= w <= r ? w : w*(double)0.5;
+	}
+	return x >= (double)0 ? r : -r;
+}
+
+#ifdef TEST_FMOD
+extern long random();
+extern double fmod();
+
+#define	NTEST	10000
+#define	NCASES	3
+
+static int nfail = 0;
+
+static void
+doit(x,y)
+double x,y;
+{
+	double ro = fmod(x,y),rn = _fmod(x,y);
+	if (ro != rn) {
+		(void)printf(" x    = 0x%08.8x %08.8x (%24.16e)\n",x,x);
+		(void)printf(" y    = 0x%08.8x %08.8x (%24.16e)\n",y,y);
+		(void)printf(" fmod = 0x%08.8x %08.8x (%24.16e)\n",ro,ro);
+		(void)printf("_fmod = 0x%08.8x %08.8x (%24.16e)\n",rn,rn);
+		(void)printf("\n");
+	}
+}
+
+main()
+{
+	register int i,cases;
+	double x,y;
+
+	srandom(12345);
+	for (i = 0; i < NTEST; i++) {
+		x = (double)random();
+		y = (double)random();
+		for (cases = 0; cases < NCASES; cases++) {
+			switch (cases) {
+			case 0:
+				break;
+			case 1:
+				y = (double)1/y; break;
+			case 2:
+				x = (double)1/x; break;
+			default:
+				abort(); break;
+			}
+			doit(x,y);
+			doit(x,-y);
+			doit(-x,y);
+			doit(-x,-y);
+		}
+	}
+	if (nfail)
+		(void)printf("Number of failures: %d (out of a total of %d)\n",
+			nfail,NTEST*NCASES*4);
+	else
+		(void)printf("No discrepancies were found\n");
+	exit(0);
+}
+#endif	/* TEST_FMOD */
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/frexp.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/frexp.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <math.h>
+
+extern double EXFUN(__logb, (double x));
+
+/* Break VALUE into a normalized fraction and an integral power of 2.  */
+double
+DEFUN(frexp, (value, exp), double value AND int *exp)
+{
+#ifdef	NAN
+  if (__isinf (value))
+    {
+      errno = EDOM;
+      *exp = 0;
+      return __copysign (NAN, value);
+    }
+#endif
+
+  if (__isnan (value))
+    {
+      errno = EDOM;
+      *exp = 0;
+      return value;
+    }
+
+  if (value == 0)
+    {
+      *exp = 0;
+      return value;
+    }
+
+  /* Add one to the exponent of the number,
+     so we have one digit before the binary point.  */
+  *exp = (int) __logb (value) + 1;
+  return ldexp (value, - *exp);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/hypot.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/hypot.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1991, 1994 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <math.h>
+
+/* Return `sqrt(x*x + y*y)'.  */
+__CONSTVALUE double
+DEFUN(hypot, (x, y), double x AND double y)
+{
+  return sqrt(x*x + y*y);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/isinf.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/isinf.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <math.h>
+#include "ieee754.h"
+
+/* Return 0 if VALUE is finite or NaN, +1 if it
+   is +Infinity, -1 if it is -Infinity.  */
+int
+DEFUN(__isinf, (value), double value)
+{
+  union ieee754_double u;
+
+  u.d = value;
+  /* An IEEE 754 infinity has an exponent with the
+     maximum possible value and a zero mantissa.  */
+  if ((u.ieee.exponent & 0x7ff) == 0x7ff &&
+      u.ieee.mantissa0 == 0 && u.ieee.mantissa1 == 0)
+    return u.ieee.negative ? -1 : 1;
+
+  return 0;
+}
+
+/* weak_alias (__isinf, isinf) */
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/j0l.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/j0l.c
@@ -0,0 +1,296 @@
+/*							j0l.c
+ *
+ *	Bessel function of order zero
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, j0l();
+ *
+ * y = j0l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns Bessel function of first kind, order zero of the argument.
+ *
+ * The domain is divided into the intervals [0, 9] and
+ * (9, infinity). In the first interval the rational approximation
+ * is (x^2 - r^2) (x^2 - s^2) (x^2 - t^2) P7(x^2) / Q8(x^2),
+ * where r, s, t are the first three zeros of the function.
+ * In the second interval the expansion is in terms of the
+ * modulus M0(x) = sqrt(J0(x)^2 + Y0(x)^2) and phase  P0(x)
+ * = atan(Y0(x)/J0(x)).  M0 is approximated by sqrt(1/x)P7(1/x)/Q7(1/x).
+ * The approximation to J0 is M0 * cos(x -  pi/4 + 1/x P5(1/x^2)/Q6(1/x^2)).
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Absolute error:
+ * arithmetic   domain      # trials      peak         rms
+ *    IEEE      0, 30       10000       2.7e-19      7.3e-20
+ *
+ *
+ */
+/*							y0l.c
+ *
+ *	Bessel function of the second kind, order zero
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double x, y, y0l();
+ *
+ * y = y0l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns Bessel function of the second kind, of order
+ * zero, of the argument.
+ *
+ * The domain is divided into the intervals [0, 5>, [5,9> and
+ * [9, infinity). In the first interval a rational approximation
+ * R(x) is employed to compute y0(x)  = R(x) + 2/pi * log(x) * j0(x).
+ *
+ * In the second interval, the approximation is
+ *     (x - p)(x - q)(x - r)(x - s)P7(x)/Q7(x)
+ * where p, q, r, s are zeros of y0(x).
+ *
+ * The third interval uses the same approximations to modulus
+ * and phase as j0(x), whence y0(x) = modulus * sin(phase).
+ *
+ * ACCURACY:
+ *
+ *  Absolute error, when y0(x) < 1; else relative error:
+ *
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      0, 30       25000       3.0e-19     7.6e-20
+ *
+ */
+
+/* Copyright 1994 by Stephen L. Moshier (moshier@world.std.com).  */
+
+#include "mathl.h"
+extern long double __polevll ( long double, long double *, int );
+extern long double __p1evll ( long double, long double *, int );
+
+/*
+j0(x) = (x^2-JZ1)(x^2-JZ2)(x^2-JZ3)P(x**2)/Q(x**2)
+0 <= x <= 9
+Relative error
+n=7, d=8
+Peak error =  8.49e-22
+Relative error spread =  2.2e-3
+*/
+static long double j0n[] = {
+ 1.296848754518641770562068596970917461302E0L,
+-3.239201943301299801017988814490822973468E3L,
+ 3.490002040733471400106951588156446469843E6L,
+-2.076797068740966813172740536268762823178E9L,
+ 7.283696461857171054940603724292997493661E11L,
+-1.487926133645291056388093978451001239544E14L,
+ 1.620335009643150402367970862340822012501E16L,
+-7.173386747526788067407034559506246493841E17L
+ };
+static long double j0d[] = {
+/* 1.000000000000000000000000000000000000000E0*/
+ 2.281959869176887763844919265666715670624E3L,
+ 2.910386840401647706984290219401654268412E6L,
+ 2.608400226578100610990921977837307261661E9L,
+ 1.752689035792859338859788285894079836315E12L,
+ 8.879132373286001289461351204912522718368E14L,
+ 3.265560832845194013668975527943185616740E17L,
+ 7.881340554308432241891814409857299717887E19L,
+ 9.466475654163919450527627558766493397282E21L
+};
+/*
+sqrt(j0^2(1/x^2) + y0^2(1/x^2)) = z P(z**2)/Q(z**2)
+z(x) = 1/sqrt(x)
+Relative error
+n=7, d=7
+Peak error =  1.80e-20
+Relative error spread =  5.1e-2
+*/
+static long double modulusn[] = {
+ 3.947542376069224461532136552047845797185E-1L,
+ 6.864682945702134624126371301477343341825E0L,
+ 1.021369773577974343843959835514109613368E1L,
+ 7.626141421290849630522661034590426845035E0L,
+ 2.842537511425216145635344663341056100390E0L,
+ 7.162842530423205720961523942028933535254E-1L,
+ 9.036664453160200052295692999857254683255E-2L,
+ 8.461833426898867839659448202505801120140E-3L
+};
+static long double modulusd[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+ 9.117176038171821115904394138261429005561E0L,
+ 1.301235226061478261480860548640027632230E1L,
+ 9.613002539386213788182145213835341179345E0L,
+ 3.569671060989910901903283335065262208244E0L,
+ 8.983920141407590632423345373045592707789E-1L,
+ 1.132577931332212304985636383878157848593E-1L,
+ 1.060533546154121770441529910796331563105E-2L
+ };
+/*
+atan(y0(x)/j0(x)) = x - pi/4 + x P(x**2)/Q(x**2)
+Absolute error
+n=5, d=6
+Peak error =  2.80e-21
+Relative error spread =  5.5e-1
+*/
+static long double phasen[] = {
+-7.356766355393571519038139469135140406247E-1L,
+-5.001635199922493694706241245828396845424E-1L,
+-7.737323518141516881715220488195636681899E-2L,
+-3.998893155826990642730404602407242779985E-3L,
+-7.496317036829964150970102768499885677420E-5L,
+-4.290885090773112963541732090289084223939E-7L
+};
+static long double phased[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+ 7.377856408614376072744766256586157817057E0L,
+ 4.285043297797736118068767291405925283657E0L,
+ 6.348446472935245102890369628706013793370E-1L,
+ 3.229866782185025048457458026131873133385E-2L,
+ 6.014932317342190404134448927950191465063E-4L,
+ 3.432708072618490390094952090444729316515E-6L
+ };
+
+#define JZ1 5.783185962946784521175995758L
+#define JZ2 30.471262343662086399078163175L
+#define JZ3 7.4887006790695183444889041310136808274810908E1L
+
+#define PIO4L 0.78539816339744830961566L
+
+long double j0l(long double x)
+{
+long double xx, y, z, modulus, phase;
+
+xx = x * x;
+if( xx < 81.0L )
+  {
+    y = (xx - JZ1) * (xx - JZ2) * (xx -JZ3);
+    y *= __polevll( xx, j0n, 7 ) / __p1evll( xx, j0d, 8 );
+    return y;
+  }
+
+y = fabsl(x);
+xx = 1.0/xx;
+phase = __polevll( xx, phasen, 5 ) / __p1evll( xx, phased, 6 );
+
+z = 1.0/y;
+modulus = __polevll( z, modulusn, 7 ) / __p1evll( z, modulusd, 7 );
+
+y = modulus * cosl( y -  PIO4L + z*phase) / sqrtl(y);
+return y;
+}
+
+
+/*
+y0(x) = 2/pi * log(x) * j0(x) + P(z**2)/Q(z**2)
+0 <= x <= 5
+Absolute error
+n=7, d=7
+Peak error =  8.55e-22
+Relative error spread =  2.7e-1
+*/
+static long double y0n[] = {
+ 1.556909814120445353690558903926596922430E4L,
+-1.464324149797947303150684329851271736158E7L,
+ 5.427926320587133391307283047780685085060E9L,
+-9.808510181632626683952255657533575381882E11L,
+ 8.747842804834934784972498894571266988554E13L,
+-3.461898868011666236538997563917952308530E15L,
+ 4.421767595991969611983299917018735928270E16L,
+-1.847183690384811186958417431043844288483E16L
+};
+static long double y0d[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+ 1.040792201755841697888585281350416537990E3L,
+ 6.256391154086099882301995151394816098690E5L,
+ 2.686702051957904669677256742116961716912E8L,
+ 8.630939306572281881328204934638848292693E10L,
+ 2.027480766502742538762944923313331185696E13L,
+ 3.167750475899536301562019307293643530456E15L,
+ 2.502813268068711844040275540632320849671E17L
+};
+
+/*
+y0(x) = (x-Y0Z1)(x-Y0Z2)(x-Y0Z3)(x-Y0Z4)P(x)/Q(x)
+4.5 <= x <= 9
+Absolute error
+n=9, d=9
+Peak error =  2.35e-20
+Relative error spread =  7.8e-13
+*/
+static long double y059n[] = {
+ 2.368715538373384869795740108286354080729E-2L,
+-1.472923738545276751401835498475289789724E0L,
+ 2.525993724177105060507377634547936257100E1L,
+ 7.727403527387097461580463446897153155336E1L,
+-4.578271827238477598563372907206784098428E3L,
+ 7.051411242092171161986020461608228436219E3L,
+ 1.951120419910720443330833105263077652526E5L,
+ 6.515211089266670755621513548872432595610E5L,
+-1.164760792144532266854968981115405821194E5L,
+-5.566567444353735925323263816754034956079E5L
+};
+static long double y059d[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+-6.235501989189125881723091161802419916592E1L,
+ 2.224790285641017194158141027000555212083E3L,
+-5.103881883748705381186322587373400863945E4L,
+ 8.772616606054526158656710844751021655708E5L,
+-1.096162986826467060920523203989531893118E7L,
+ 1.083335477747278958468238227109848215017E8L,
+-7.045635226159434678832858770683824287226E8L,
+ 3.518324187204647941098046647734000055759E9L,
+ 1.173085288957116938494111248664763079367E9L
+ };
+
+#define TWOOPI 6.36619772367581343075535E-1L
+#define Y0Z1 3.9576784193148578683756771869174012814186038E0L
+#define Y0Z2 7.0860510603017726976236245968203524689715104E0L
+#define Y0Z3 1.0222345043496417018992042276342187125994060E1L
+#define Y0Z4 1.3361097473872763478267694585713786426579135E1L
+#define MAXNUML 1.189731495357231765021263853E4932L
+
+long double y0l(long double x)
+{
+long double xx, y, z, modulus, phase;
+
+if( x < 0.0 )
+  {
+    return (-MAXNUML);
+  }
+xx = x * x;
+if( xx < 81.0L )
+  {
+    if( xx < 20.25L )
+      {
+	y = TWOOPI * logl(x) * j0l(x);
+	y += __polevll( xx, y0n, 7 ) / __p1evll( xx, y0d, 7 );
+      }
+    else
+      {
+	y = (x - Y0Z1)*(x - Y0Z2)*(x - Y0Z3)*(x - Y0Z4);
+	y *= __polevll( x, y059n, 9 ) / __p1evll( x, y059d, 9 );
+      }
+    return y;
+  }
+
+y = fabsl(x);
+xx = 1.0/xx;
+phase = __polevll( xx, phasen, 5 ) / __p1evll( xx, phased, 6 );
+
+z = 1.0/y;
+modulus = __polevll( z, modulusn, 7 ) / __p1evll( z, modulusd, 7 );
+
+y = modulus * sinl( y -  PIO4L + z*phase) / sqrtl(y);
+return y;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/j1.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/j1.c
@@ -0,0 +1,188 @@
+#include <math.h>
+
+/*
+	floating point Bessel's function
+	of the first and second kinds
+	of order one
+
+	j1(x) returns the value of J1(x)
+	for all real values of x.
+
+	There are no error returns.
+	Calls sin, cos, sqrt.
+
+	There is a niggling bug in J1 which
+	causes errors up to 2e-16 for x in the
+	interval [-8,8].
+	The bug is caused by an inappropriate order
+	of summation of the series.  rhm will fix it
+	someday.
+
+	Coefficients are from Hart & Cheney.
+	#6050 (20.98D)
+	#6750 (19.19D)
+	#7150 (19.35D)
+
+	y1(x) returns the value of Y1(x)
+	for positive real values of x.
+	For x<=0, error number EDOM is set and a
+	large negative value is returned.
+
+	Calls sin, cos, sqrt, log, j1.
+
+	The values of Y1 have not been checked
+	to more than ten places.
+
+	Coefficients are from Hart & Cheney.
+	#6447 (22.18D)
+	#6750 (19.19D)
+	#7150 (19.35D)
+*/
+
+static void asympt(double);
+static double pzero, qzero;
+static double tpi	= .6366197723675813430755350535e0;
+static double pio4	= .7853981633974483096156608458e0;
+static double p1[] = {
+	0.581199354001606143928050809e21,
+	-.6672106568924916298020941484e20,
+	0.2316433580634002297931815435e19,
+	-.3588817569910106050743641413e17,
+	0.2908795263834775409737601689e15,
+	-.1322983480332126453125473247e13,
+	0.3413234182301700539091292655e10,
+	-.4695753530642995859767162166e7,
+	0.2701122710892323414856790990e4,
+};
+static double q1[] = {
+	0.1162398708003212287858529400e22,
+	0.1185770712190320999837113348e20,
+	0.6092061398917521746105196863e17,
+	0.2081661221307607351240184229e15,
+	0.5243710262167649715406728642e12,
+	0.1013863514358673989967045588e10,
+	0.1501793594998585505921097578e7,
+	0.1606931573481487801970916749e4,
+	1.0,
+};
+static double p2[] = {
+	-.4435757816794127857114720794e7,
+	-.9942246505077641195658377899e7,
+	-.6603373248364939109255245434e7,
+	-.1523529351181137383255105722e7,
+	-.1098240554345934672737413139e6,
+	-.1611616644324610116477412898e4,
+	0.0,
+};
+static double q2[] = {
+	-.4435757816794127856828016962e7,
+	-.9934124389934585658967556309e7,
+	-.6585339479723087072826915069e7,
+	-.1511809506634160881644546358e7,
+	-.1072638599110382011903063867e6,
+	-.1455009440190496182453565068e4,
+	1.0,
+};
+static double p3[] = {
+	0.3322091340985722351859704442e5,
+	0.8514516067533570196555001171e5,
+	0.6617883658127083517939992166e5,
+	0.1849426287322386679652009819e5,
+	0.1706375429020768002061283546e4,
+	0.3526513384663603218592175580e2,
+	0.0,
+};
+static double q3[] = {
+	0.7087128194102874357377502472e6,
+	0.1819458042243997298924553839e7,
+	0.1419460669603720892855755253e7,
+	0.4002944358226697511708610813e6,
+	0.3789022974577220264142952256e5,
+	0.8638367769604990967475517183e3,
+	1.0,
+};
+static double p4[] = {
+	-.9963753424306922225996744354e23,
+	0.2655473831434854326894248968e23,
+	-.1212297555414509577913561535e22,
+	0.2193107339917797592111427556e20,
+	-.1965887462722140658820322248e18,
+	0.9569930239921683481121552788e15,
+	-.2580681702194450950541426399e13,
+	0.3639488548124002058278999428e10,
+	-.2108847540133123652824139923e7,
+	0.0,
+};
+static double q4[] = {
+	0.5082067366941243245314424152e24,
+	0.5435310377188854170800653097e22,
+	0.2954987935897148674290758119e20,
+	0.1082258259408819552553850180e18,
+	0.2976632125647276729292742282e15,
+	0.6465340881265275571961681500e12,
+	0.1128686837169442121732366891e10,
+	0.1563282754899580604737366452e7,
+	0.1612361029677000859332072312e4,
+	1.0,
+};
+
+double j1(double arg)
+{
+	double xsq, n, d, x;
+	int i;
+
+	x = arg;
+	if(x < 0.) x = -x;
+	if(x > 8.){
+		asympt(x);
+		n = x - 3.*pio4;
+		n = sqrt(tpi/x)*(pzero*cos(n) - qzero*sin(n));
+		if(arg <0.) n = -n;
+		return(n);
+	}
+	xsq = x*x;
+	for(n=0,d=0,i=8;i>=0;i--){
+		n = n*xsq + p1[i];
+		d = d*xsq + q1[i];
+	}
+	return(arg*n/d);
+}
+
+double y1(double arg)
+{
+	double xsq, n, d, x;
+	int i;
+
+	x = arg;
+	if(x <= 0.){
+		return(-HUGE_VAL);
+	}
+	if(x > 8.){
+		asympt(x);
+		n = x - 3*pio4;
+		return(sqrt(tpi/x)*(pzero*sin(n) + qzero*cos(n)));
+	}
+	xsq = x*x;
+	for(n=0,d=0,i=9;i>=0;i--){
+		n = n*xsq + p4[i];
+		d = d*xsq + q4[i];
+	}
+	return(x*n/d + tpi*(j1(x)*log(x)-1./x));
+}
+
+static void asympt(double arg)
+{
+	double zsq, n, d;
+	int i;
+	zsq = 64./(arg*arg);
+	for(n=0,d=0,i=6;i>=0;i--){
+		n = n*zsq + p2[i];
+		d = d*zsq + q2[i];
+	}
+	pzero = n/d;
+	for(n=0,d=0,i=6;i>=0;i--){
+		n = n*zsq + p3[i];
+		d = d*zsq + q3[i];
+	}
+	qzero = (8./arg)*(n/d);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/j1l.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/j1l.c
@@ -0,0 +1,281 @@
+/*							j1l.c
+ *
+ *	Bessel function of order one
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, j1l();
+ *
+ * y = j1l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns Bessel function of order one of the argument.
+ *
+ * The domain is divided into the intervals [0, 9] and
+ * (9, infinity). In the first interval the rational approximation
+ * is (x^2 - r^2) (x^2 - s^2) (x^2 - t^2) x P8(x^2) / Q8(x^2),
+ * where r, s, t are the first three zeros of the function.
+ * In the second interval the expansion is in terms of the
+ * modulus M1(x) = sqrt(J1(x)^2 + Y1(x)^2) and phase  P1(x)
+ * = atan(Y1(x)/J1(x)).  M1 is approximated by sqrt(1/x)P7(1/x)/Q8(1/x).
+ * The approximation to j1 is M1 * cos(x -  3 pi/4 + 1/x P5(1/x^2)/Q6(1/x^2)).
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Absolute error:
+ * arithmetic   domain      # trials      peak         rms
+ *    IEEE      0, 30       10000       1.7e-19      5.0e-20
+ *
+ *
+ */
+/*							y1l.c
+ *
+ *	Bessel function of the second kind, order zero
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double x, y, y1l();
+ *
+ * y = y1l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns Bessel function of the second kind, of order
+ * zero, of the argument.
+ *
+ * The domain is divided into the intervals [0, 4.5>, [4.5,9> and
+ * [9, infinity). In the first interval a rational approximation
+ * R(x) is employed to compute y0(x)  = R(x) + 2/pi * log(x) * j0(x).
+ *
+ * In the second interval, the approximation is
+ *     (x - p)(x - q)(x - r)(x - s)P9(x)/Q10(x)
+ * where p, q, r, s are zeros of y1(x).
+ *
+ * The third interval uses the same approximations to modulus
+ * and phase as j1(x), whence y1(x) = modulus * sin(phase).
+ *
+ * ACCURACY:
+ *
+ *  Absolute error, when y0(x) < 1; else relative error:
+ *
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      0, 30       6000        2.4e-19     5.4e-20
+ *
+ */
+
+/* Copyright 1994 by Stephen L. Moshier (moshier@world.std.com).  */
+
+#include "mathl.h"
+extern long double __polevll ( long double, long double *, int );
+extern long double __p1evll ( long double, long double *, int );
+
+/*
+j1(x) = (x^2-r0^2)(x^2-r1^2)(x^2-r2^2) x P(x**2)/Q(x**2)
+Relative error
+n=8, d=8
+Peak error =  2e-21
+*/
+static long double j1n[] = {
+-2.634697796221277628971935439379100448941E-4L,
+ 9.313297622796327912616990544807729349816E-1L,
+-1.462801427977939339087861462016763117614E3L,
+ 1.320001295393312144946720253523751495344E6L,
+-7.411832711954540428424579722022697274252E8L,
+ 2.626500686552841932403375456823890030733E11L,
+-5.682630730221834709333595924862737385674E13L,
+ 6.800062979972634469823465019593889535036E15L,
+-3.414700974444745667483143593080298025264E17L
+ };
+static long double j1d[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+ 2.952679519729437457329616170307633853371E3L,
+ 4.787239263438296747732226800464625857306E6L,
+ 5.375447329578075439197694561828270959740E9L,
+ 4.468662138862678294901755275226730274220E12L,
+ 2.769597563759616070852381975767135596290E15L,
+ 1.233678068848311511940047189841753732303E18L,
+ 3.573258746896955995244858202885402209284E20L,
+ 5.107790455161415784613110686083256035323E22L
+};
+/*
+sqrt(j0^2(1/x^2) + y0^2(1/x^2)) = z P(z**2)/Q(z**2)
+z(x) = 1/sqrt(x)
+Relative error
+n=7, d=8
+Peak error =  1.35e=20
+Relative error spread =  9.0e0
+*/
+static long double modulusn[] = {
+-5.041742205078442098873946599818859411841E0L,
+ 3.918474430130242177354760505592118707545E-1L,
+ 2.527521168680500659056387541731679323679E0L,
+ 7.172146812845906480742580751162395880700E0L,
+ 2.859499532295180940060097685686785747839E0L,
+ 1.014671139779858141347461961442252531091E0L,
+ 1.255798064266130869131769135327120168414E-1L,
+ 1.596507617085714650238013674302102214586E-2L
+};
+static long double modulusd[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+-6.233092094568239317498213232200456266608E0L,
+-9.214128701852838347001714615803119950789E-1L,
+ 2.531772200570435289832000302297822691539E0L,
+ 8.755081357265851765639996579311407253229E0L,
+ 3.554340386955608261462733259897195898764E0L,
+ 1.267949948774331531237417342523472412319E0L,
+ 1.573909467558180942219276563149698450074E-1L,
+ 2.000925566825407466160190735195649280593E-2L
+ };
+/*
+atan(y1(x)/j1(x))  =  x - 3pi/4 + z P(z**2)/Q(z**2)
+z(x) = 1/x
+Absolute error
+n=5, d=6
+Peak error =  4.83e-21
+Relative error spread =  1.9e0
+*/
+static long double phasen[] = {
+ 2.010456367705144783933016123752706035207E0L,
+ 1.587378144541918176658121923411891505725E0L,
+ 2.682837461073751055565177542176613982515E-1L,
+ 1.472572645054468815027121251529744762234E-2L,
+ 2.884976126715926258585500789700568171816E-4L,
+ 1.708502235134706284899170935145399268617E-6L
+};
+static long double phased[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+ 6.809332495854873089362409327980929501353E0L,
+ 4.518597941618813112664962212253836700838E0L,
+ 7.320149039410806471100853405098354700190E-1L,
+ 3.960155028960712309813713456399687003948E-2L,
+ 7.713202197319040439861232615648837506269E-4L,
+ 4.556005960359216767984395285780473266643E-6L
+ };
+
+#define JZ1 1.4681970642123893257219777768630106989681587E1L
+#define JZ2 4.9218456321694603670267082846388138932425412E1L
+#define JZ3 1.0349945389513658033222363253561305574983502E2L
+
+#define THPIO4L  2.35619449019234492885L
+
+long double j1l(long double x)
+{
+long double xx, y, z, modulus, phase;
+
+xx = x * x;
+if( xx < 81.0L )
+  {
+    y = (xx - JZ1) * (xx - JZ2) * (xx - JZ3);
+    y *= x * __polevll( xx, j1n, 8 ) / __p1evll( xx, j1d, 8 );
+    return y;
+  }
+
+y = fabsl(x);
+xx = 1.0/xx;
+phase = __polevll( xx, phasen, 5 ) / __p1evll( xx, phased, 6 );
+
+z = 1.0/y;
+modulus = __polevll( z, modulusn, 7 ) / __p1evll( z, modulusd, 8 );
+
+y = modulus * cosl( y -  THPIO4L + z*phase) / sqrtl(y);
+if( x < 0 )
+  y = -y;
+return y;
+}
+
+static long double y1n[] = {
+-1.288901054372751879530799223223505257692E5L,
+ 9.914315981558815369372336678918231933103E7L,
+-2.906793378120403577273915213389829871402E10L,
+ 3.954354656937677136265837177266774549541E12L,
+-2.445982226888344140153571265516582079837E14L,
+ 5.685362960165615942886131910189352872528E15L,
+-2.158855258453711703120399853735329573110E16L
+};
+static long double y1d[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+ 8.926354644853231136072991636781412786125E2L,
+ 4.679841933793707979658529184983101722128E5L,
+ 1.775133253792677466650594382943712081101E8L,
+ 5.089532584184822833415809008343104067480E10L,
+ 1.076474894829072923244442357703372832195E13L,
+ 1.525917240904692387994338842633536676896E15L,
+ 1.101136026928555260167699409793359571793E17L
+};
+static long double y159n[] = {
+-6.806634906054210550895796232243478627879E-1L,
+ 4.306669585790359450531735079332477032239E1L,
+-9.230477746767243316013573089219930917796E2L,
+ 6.171186628598134035236603420969585848071E3L,
+ 2.096869860275353982829414221776143235491E4L,
+-1.238961670382216747944146253091813185559E5L,
+-1.781314136808997406108546510088125743955E6L,
+-1.803400156074242435454306040864758160815E6L,
+-1.155761550219364178626921880155041761746E6L,
+ 3.112221202330688509818373491140459519285E5L
+};
+static long double y159d[] = {
+/* 1.000000000000000000000000000000000000000E0 */
+-6.181482377814679766978324825945117512812E1L,
+ 2.238187927382180589098927722621122192486E3L,
+-5.225317824142187494325968315136322493497E4L,
+ 9.217235006983512475118388815131670860571E5L,
+-1.183757638771741974520896241943158149865E7L,
+ 1.208072488974110742912058706805732230596E8L,
+-8.193431077523942651172530209520018834293E8L,
+ 4.282669747880013349980886241568066930618E9L,
+-1.171523459555524458807562674565375794753E9L,
+ 1.078445545755236785691969932840418530054E8L
+};
+
+#define MAXNUML 1.189731495357231765021263853E4932L
+#define TWOOPI 6.36619772367581343075535E-1L
+#define THPIO4 2.35619449019234492885L
+#define Y1Z1 2.1971413260310170351490335626989662730530183E0L
+#define Y1Z2 5.4296810407941351327720051908525841965837575E0L
+#define Y1Z3 8.5960058683311689264296061801639678511029216E0L
+#define Y1Z4 1.1749154830839881243399421939922350714301166E1L
+
+long double y1l(long double x)
+{
+long double xx, y, z, modulus, phase;
+
+if( x < 0.0 )
+  {
+    return (-MAXNUML);
+  }
+z = 1.0/x;
+xx = x * x;
+if( xx < 81.0L )
+  {
+    if( xx < 20.25L )
+      {
+	y = TWOOPI * (logl(x) * j1l(x) - z);
+	y += x * __polevll( xx, y1n, 6 ) / __p1evll( xx, y1d, 7 );
+      }
+    else
+      {
+	y = (x - Y1Z1)*(x - Y1Z2)*(x - Y1Z3)*(x - Y1Z4);
+	y *= __polevll( x, y159n, 9 ) / __p1evll( x, y159d, 10 );
+      }
+    return y;
+  }
+
+xx = 1.0/xx;
+phase = __polevll( xx, phasen, 5 ) / __p1evll( xx, phased, 6 );
+
+modulus = __polevll( z, modulusn, 7 ) / __p1evll( z, modulusd, 8 );
+
+z = modulus * sinl( x -  THPIO4L + z*phase) / sqrtl(x);
+return z;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/jn.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/jn.c
@@ -0,0 +1,119 @@
+#include <math.h>
+
+/*
+	floating point Bessel's function of
+	the first and second kinds and of
+	integer order.
+
+	int n;
+	double x;
+	jn(n,x);
+
+	returns the value of Jn(x) for all
+	integer values of n and all real values
+	of x.
+
+	There are no error returns.
+	Calls j0, j1.
+
+	For n=0, j0(x) is called,
+	for n=1, j1(x) is called,
+	for n<x, forward recursion us used starting
+	from values of j0(x) and j1(x).
+	for n>x, a continued fraction approximation to
+	j(n,x)/j(n-1,x) is evaluated and then backward
+	recursion is used starting from a supposed value
+	for j(n,x). The resulting value of j(0,x) is
+	compared with the actual value to correct the
+	supposed value of j(n,x).
+
+	yn(n,x) is similar in all respects, except
+	that forward recursion is used for all
+	values of n>1.
+*/
+
+double jn(int n, double x)
+{
+	int i, sign;
+	double a, b, temp;
+	double xsq, t;
+
+/*
+                  n
+   J  (x)  =  (-1)   J (x)
+    -n                n
+                  n
+   J (-x)  =  (-1)   J (x)
+    n                 n
+ */
+	sign = 1;
+	if(n<0){
+		n = -n;
+		if( n & 1 )
+		  sign = -1;
+	}
+	if( x < 0.0 )
+	  {
+	    if( n & 1 )
+	      sign = -sign;
+	    x = -x;
+	  }
+	if(n==0) return(j0(x));
+	if(n==1) return(sign*j1(x));
+	if(x == 0.) return(0.);
+	if(n>x) goto recurs;
+
+/* Note, forward recurrence for Jn is numerically unstable.
+   This should be fixed sometime.  */
+	a = j0(x);
+	b = j1(x);
+	for(i=1;i<n;i++){
+		temp = b;
+		b = (2.*i/x)*b - a;
+		a = temp;
+	}
+	return(sign*b);
+
+recurs:
+	xsq = x*x;
+	for(t=0,i=n+16;i>n;i--){
+		t = xsq/(2.*i - t);
+	}
+	t = x/(2.*n-t);
+
+	a = t;
+	b = 1;
+	for(i=n-1;i>0;i--){
+		temp = b;
+		b = (2.*i/x)*b - a;
+		a = temp;
+	}
+	return(sign*t*j0(x)/b);
+}
+
+double yn(int n, double x)
+{
+	int i;
+	int sign;
+	double a, b, temp;
+
+	if (x <= 0) {
+		return(-HUGE_VAL);
+	}
+	sign = 1;
+	if(n<0){
+		n = -n;
+		if(n%2 == 1) sign = -1;
+	}
+	if(n==0) return(y0(x));
+	if(n==1) return(sign*y1(x));
+
+	a = y0(x);
+	b = y1(x);
+	for(i=1;i<n;i++){
+		temp = b;
+		b = (2.*i/x)*b - a;
+		a = temp;
+	}
+	return(sign*b);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/jnl.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/jnl.c
@@ -0,0 +1,120 @@
+/*
+	floating point Bessel's function of
+	the first and second kinds and of
+	integer order.
+
+	int n;
+	double x;
+	jn(n,x);
+
+	returns the value of Jn(x) for all
+	integer values of n and all real values
+	of x.
+
+	There are no error returns.
+	Calls j0l, j1l.
+
+	For n=0, j0l(x) is called,
+	for n=1, j1l(x) is called,
+	for n<x, forward recursion us used starting
+	from values of j0l(x) and j1l(x).
+	for n>x, a continued fraction approximation to
+	j(n,x)/j(n-1,x) is evaluated and then backward
+	recursion is used starting from a supposed value
+	for j(n,x). The resulting value of j(0,x) is
+	compared with the actual value to correct the
+	supposed value of j(n,x).
+
+	yn(n,x) is similar in all respects, except
+	that forward recursion is used for all
+	values of n>1.
+*/
+
+#include "mathl.h"
+
+/* long double j0l(), j1l(), y0l(), y1l(); */
+
+long double jnl(int n, long double x)
+{
+	int i, sign;
+	long double a, b, temp;
+	long double xsq, t;
+
+/*
+                  n
+   J  (x)  =  (-1)   J (x)
+    -n                n
+                  n
+   J (-x)  =  (-1)   J (x)
+    n                 n
+ */
+	sign = 1;
+	if(n<0){
+		n = -n;
+		if( n & 1 )
+		  sign = -1;
+	}
+	if( x < 0.0L )
+	  {
+	    if( n & 1 )
+	      sign = -sign;
+	    x = -x;
+	  }
+	if(n==0) return(j0l(x));
+	if(n==1) return(sign*j1l(x));
+	if(x == 0.L) return(0.L);
+
+	if(n>x) goto recurs;
+
+	a = j0l(x);
+	b = j1l(x);
+	for(i=1;i<n;i++){
+		temp = b;
+		b = (2.L*i/x)*b - a;
+		a = temp;
+	}
+	return(sign*b);
+recurs:
+
+	xsq = x*x;
+	for(t=0,i=n+16;i>n;i--){
+		t = xsq/(2.L*i - t);
+	}
+	t = x/(2.L*n-t);
+
+	a = t;
+	b = 1;
+	for(i=n-1;i>0;i--){
+		temp = b;
+		b = (2.L*i/x)*b - a;
+		a = temp;
+	}
+	return(sign*t*j0l(x)/b);
+}
+
+long double ynl(int n, long double x)
+{
+	int i;
+	int sign;
+	long double a, b, temp;
+
+	if (x <= 0) {
+		return(-1.189731495357231765021263853E4932L);
+	}
+	sign = 1;
+	if(n<0){
+		n = -n;
+		if(n%2 == 1) sign = -1;
+	}
+	if(n==0) return(y0l(x));
+	if(n==1) return(sign*y1l(x));
+
+	a = y0l(x);
+	b = y1l(x);
+	for(i=1;i<n;i++){
+		temp = b;
+		b = (2.L*i/x)*b - a;
+		a = temp;
+	}
+	return(sign*b);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/ldexp.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/ldexp.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <math.h>
+
+/* Return X times (two to the EXP power).  */
+double
+DEFUN(ldexp, (x, exp), register double x AND register int exp)
+{
+  return x * pow(2.0, (double) exp);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/lgamma.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/lgamma.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)lgamma.c	5.3 (Berkeley) 9/22/88";
+#endif /* not lint */
+#endif
+
+/*
+	C program for floating point log Gamma function
+
+	lgamma(x) computes the log of the absolute
+	value of the Gamma function.
+	The sign of the Gamma function is returned in the
+	external quantity signgam.
+
+	The coefficients for expansion around zero
+	are #5243 from Hart & Cheney; for expansion
+	around infinity they are #5404.
+
+	Calls log, floor and sin.
+*/
+
+#if 0
+#include "mathimpl.h"
+#else
+#include <math.h>
+#endif
+#if defined(vax)||defined(tahoe)
+#include <errno.h>
+#endif	/* defined(vax)||defined(tahoe) */
+
+int signgam;
+
+static const double goobie = 0.9189385332046727417803297;  /* log(2*pi)/2 */
+static const double pi	   = 3.1415926535897932384626434;
+
+#define M 6
+#define N 8
+static const double p1[] = {
+	0.83333333333333101837e-1,
+	-.277777777735865004e-2,
+	0.793650576493454e-3,
+	-.5951896861197e-3,
+	0.83645878922e-3,
+	-.1633436431e-2,
+};
+static const double p2[] = {
+	-.42353689509744089647e5,
+	-.20886861789269887364e5,
+	-.87627102978521489560e4,
+	-.20085274013072791214e4,
+	-.43933044406002567613e3,
+	-.50108693752970953015e2,
+	-.67449507245925289918e1,
+	0.0,
+};
+static const double q2[] = {
+	-.42353689509744090010e5,
+	-.29803853309256649932e4,
+	0.99403074150827709015e4,
+	-.15286072737795220248e4,
+	-.49902852662143904834e3,
+	0.18949823415702801641e3,
+	-.23081551524580124562e2,
+	0.10000000000000000000e1,
+};
+
+static double pos(double), neg(double), asym(double);
+
+double
+lgamma(double arg)
+{
+
+	signgam = 1;
+	if(arg <= 0.) return(neg(arg));
+	if(arg > 8.) return(asym(arg));
+	return(log(pos(arg)));
+}
+
+static double
+asym(double arg)
+{
+	double n, argsq;
+	int i;
+
+	/* Avoid overflow of arg*arg.  */
+	n = 0.0;
+	if(arg > 1.0e8)
+	  goto noasym;
+
+	argsq = 1./(arg*arg);
+	for(i=M-1; i>=0; i--){
+		n = n*argsq + p1[i];
+	}
+noasym:
+	return((arg-.5)*log(arg) - arg + goobie + n/arg);
+}
+
+static double
+neg(double arg)
+{
+	double t;
+
+	arg = -arg;
+     /*
+      * to see if arg were a true integer, the old code used the
+      * mathematically correct observation:
+      * sin(n*pi) = 0 <=> n is an integer.
+      * but in finite precision arithmetic, sin(n*PI) will NEVER
+      * be zero simply because n*PI is a rational number.  hence
+      *	it failed to work with our newer, more accurate sin()
+      * which uses true pi to do the argument reduction...
+      *	temp = sin(pi*arg);
+      */
+	t = floor(arg);
+	if (arg - t  > 0.5e0)
+	    t += 1.e0;				/* t := integer nearest arg */
+#if defined(vax)||defined(tahoe)
+	if (arg == t) {
+	    return(infnan(ERANGE));		/* +INF */
+	}
+#endif	/* defined(vax)||defined(tahoe) */
+	signgam = (int) (t - 2*floor(t/2));	/* signgam =  1 if t was odd, */
+						/*            0 if t was even */
+	signgam = signgam - 1 + signgam;	/* signgam =  1 if t was odd, */
+						/*           -1 if t was even */
+	t = arg - t;				/*  -0.5 <= t <= 0.5 */
+	if (t < 0.e0) {
+	    t = -t;
+	    signgam = -signgam;
+	}
+	return(-log(arg*pos(arg)*sin(pi*t)/pi));
+}
+
+static double
+pos(double arg)
+{
+	double n, d, s;
+	register i;
+
+	if(arg < 2.) return(pos(arg+1.)/arg);
+	if(arg > 3.) return((arg-1.)*pos(arg-1.));
+
+	s = arg - 2.;
+	for(n=0,d=0,i=N-1; i>=0; i--){
+		n = n*s + p2[i];
+		d = d*s + q2[i];
+	}
+	return(n/d);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/lgammal.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/lgammal.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+/* Coefficients for long double precision by Stephen L. Moshier
+   (moshier@world.std.com).  This routine was spot chaecked at
+   10,000 random arguments between -40 and +40.  The largest error
+   observed was 2.2e-19.  Error criterion was absolute for function
+   value < 1, relative otherwise.  */
+
+#if 0
+#ifndef lint
+static char sccsid[] = "@(#)lgamma.c	5.3 (Berkeley) 9/22/88";
+#endif /* not lint */
+#endif
+
+/*
+	C program for floating point log Gamma function
+
+	lgamma(x) computes the log of the absolute
+	value of the Gamma function.
+	The sign of the Gamma function is returned in the
+	external quantity signgaml.
+
+	The coefficients for expansion around zero
+	are #5243 from Hart & Cheney; for expansion
+	around infinity they are #5404.
+
+	Calls log, floor and sin.
+*/
+#include "mathl.h"
+long double floorl(long double);
+long double logl(long double);
+long double sinl(long double);
+
+#if 0
+#include "mathimpl.h"
+#else
+#include <math.h>
+#endif
+#if defined(vax)||defined(tahoe)
+#include <errno.h>
+#endif	/* defined(vax)||defined(tahoe) */
+
+int signgaml;
+
+  /* log(2*pi)/2 */
+static const long double goobie = 0.9189385332046727417803297L;
+static const long double pi   = 3.1415926535897932384626434L;
+
+/*
+log gamma(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x P(1/x^2)
+Relative error
+n=6, d=0
+Peak error =  1.51e-21
+Relative error spread =  5.7e-21
+*/
+#define M 7
+static const long double p1[] = {
+ 8.33333333333333144750e-2L,
+-2.77777777775034960344e-3L,
+ 7.93650779585507075567e-4L,
+-5.95234585176568851461e-4L,
+ 8.41272329732249808063e-4L,
+-1.88080193811937690718e-3L,
+ 4.88502614243227078116e-3L
+};
+/*
+gamma(x+2) = P(x)/Q(x)
+Relative error
+n=7, d=8
+Peak error =  1.84e-20
+Relative error spread =  8.4e-23
+*/
+#define N 9
+static const long double p2[] = {
+-7.15743521530849602425e4L,
+-5.99650230220855581642e4L,
+-2.59780216007146401957e4L,
+-7.96667499622741999770e3L,
+-1.70730828800510297666e3L,
+-2.92929976820724030353e2L,
+-3.25157411956062339893e1L,
+-3.01525602666895735709e0L,
+ 0.0L
+};
+static const long double q2[] = {
+-7.15743521530849602412e4L,
+-2.97045081369399940529e4L,
+ 1.60577839621734713377e4L,
+ 3.31667508019495079814e3L,
+-1.98526250512761318471e3L,
+ 5.69440799097468430177e1L,
+ 8.85946791747759881659e1L,
+-1.67955233807178858919e1L,
+ 1.00000000000000000000e0L,
+};
+
+static long double pos(long double);
+static long double neg(long double);
+static long double asym(long double);
+
+long double
+lgammal(long double arg)
+{
+
+	signgaml = 1;
+	if(arg <= 0.L) return(neg(arg));
+	if(arg > 8.L) return(asym(arg));
+	return(logl(pos(arg)));
+}
+
+static long double
+asym(long double arg)
+{
+	long double n, argsq;
+	int i;
+
+	n = 0.0L;
+
+	/* Avoid overflow of arg*arg. */
+	if(arg > 1.0e10L)
+	  goto noexpan;
+
+	argsq = 1./(arg*arg);
+	for(i=M-1; i>=0; i--){
+		n = n*argsq + p1[i];
+	}
+noexpan:
+	return((arg-.5L)*logl(arg) - arg + goobie + n/arg);
+}
+
+static long double
+neg(long double arg)
+{
+	long double t;
+
+	arg = -arg;
+     /*
+      * to see if arg were a true integer, the old code used the
+      * mathematically correct observation:
+      * sin(n*pi) = 0 <=> n is an integer.
+      * but in finite precision arithmetic, sin(n*PI) will NEVER
+      * be zero simply because n*PI is a rational number.  hence
+      *	it failed to work with our newer, more accurate sin()
+      * which uses true pi to do the argument reduction...
+      *	temp = sin(pi*arg);
+      */
+	t = floorl(arg);
+	if (arg - t  > 0.5e0L)
+	    t += 1.e0L;				/* t := integer nearest arg */
+#if defined(vax)||defined(tahoe)
+	if (arg == t) {
+	    return(__infnan(ERANGE));		/* +INF */
+	}
+#endif	/* defined(vax)||defined(tahoe) */
+	signgaml = (int) (t - 2*floorl(t/2));	/* signgam =  1 if t was odd, */
+						/*            0 if t was even */
+	signgaml = signgam - 1 + signgam;	/* signgam =  1 if t was odd, */
+						/*           -1 if t was even */
+	t = arg - t;				/*  -0.5 <= t <= 0.5 */
+	if (t < 0.e0L) {
+	    t = -t;
+	    signgaml = -signgaml;
+	}
+	return(-logl(arg*pos(arg)*sinl(pi*t)/pi));
+}
+
+static long double
+pos(long double arg)
+{
+	long double n, d, s;
+	register i;
+
+	if(arg < 2.L) return(pos(arg+1.L)/arg);
+	if(arg > 3.L) return((arg-1.0L)*pos(arg-1.0L));
+
+	s = arg - 2.0L;
+/*	for(n=0,d=0,i=N-1; i>=0; i--){*/
+/*
+	n = 0.0L;
+	d = 0.0L;
+*/
+	for(n=0,d=0,i=N-1; i>=0; i--){
+		n = n*s + p2[i];
+		d = d*s + q2[i];
+	}
+	return(n/d);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/log.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/log.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log.c	8.2 (Berkeley) 11/30/93";
+#endif /* not lint */
+
+#include <math.h>
+#include <errno.h>
+
+#include "mathimpl.h"
+
+extern double __logb __P((double));
+
+/* Table-driven natural logarithm.
+ *
+ * This code was derived, with minor modifications, from:
+ *	Peter Tang, "Table-Driven Implementation of the
+ *	Logarithm in IEEE Floating-Point arithmetic." ACM Trans.
+ *	Math Software, vol 16. no 4, pp 378-400, Dec 1990).
+ *
+ * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256,
+ * where F = j/128 for j an integer in [0, 128].
+ *
+ * log(2^m) = log2_hi*m + log2_tail*m
+ * since m is an integer, the dominant term is exact.
+ * m has at most 10 digits (for subnormal numbers),
+ * and log2_hi has 11 trailing zero bits.
+ *
+ * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h
+ * logF_hi[] + 512 is exact.
+ *
+ * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ...
+ * the leading term is calculated to extra precision in two
+ * parts, the larger of which adds exactly to the dominant
+ * m and F terms.
+ * There are two cases:
+ *	1. when m, j are non-zero (m | j), use absolute
+ *	   precision for the leading term.
+ *	2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
+ *	   In this case, use a relative precision of 24 bits.
+ * (This is done differently in the original paper)
+ *
+ * Special cases:
+ *	0	return signalling -Inf
+ *	neg	return signalling NaN
+ *	+Inf	return +Inf
+*/
+
+#if defined(vax) || defined(tahoe)
+#define _IEEE		0
+#define TRUNC(x)	x = (double) (float) (x)
+#else
+#ifdef _IEEE
+#undef _IEEE
+#endif /* _IEEE */
+#define _IEEE		1
+#define endian		(((*(int *) &one)) ? 1 : 0)
+#define TRUNC(x)	*(((int *) &x) + endian) &= 0xf8000000
+#ifdef infnan
+#undef infnan
+#endif /* infnan */
+#define infnan(x)	0.0
+#endif
+
+#define N 128
+
+/* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
+ * Used for generation of extend precision logarithms.
+ * The constant 35184372088832 is 2^45, so the divide is exact.
+ * It ensures correct reading of logF_head, even for inaccurate
+ * decimal-to-binary conversion routines.  (Everybody gets the
+ * right answer for integers less than 2^53.)
+ * Values for log(F) were generated using error < 10^-57 absolute
+ * with the bc -l package.
+*/
+static double	A1 = 	  .08333333333333178827;
+static double	A2 = 	  .01250000000377174923;
+static double	A3 =	 .002232139987919447809;
+static double	A4 =	.0004348877777076145742;
+
+static double logF_head[N+1] = {
+	0.,
+	.007782140442060381246,
+	.015504186535963526694,
+	.023167059281547608406,
+	.030771658666765233647,
+	.038318864302141264488,
+	.045809536031242714670,
+	.053244514518837604555,
+	.060624621816486978786,
+	.067950661908525944454,
+	.075223421237524235039,
+	.082443669210988446138,
+	.089612158689760690322,
+	.096729626458454731618,
+	.103796793681567578460,
+	.110814366340264314203,
+	.117783035656430001836,
+	.124703478501032805070,
+	.131576357788617315236,
+	.138402322859292326029,
+	.145182009844575077295,
+	.151916042025732167530,
+	.158605030176659056451,
+	.165249572895390883786,
+	.171850256926518341060,
+	.178407657472689606947,
+	.184922338493834104156,
+	.191394852999565046047,
+	.197825743329758552135,
+	.204215541428766300668,
+	.210564769107350002741,
+	.216873938300523150246,
+	.223143551314024080056,
+	.229374101064877322642,
+	.235566071312860003672,
+	.241719936886966024758,
+	.247836163904594286577,
+	.253915209980732470285,
+	.259957524436686071567,
+	.265963548496984003577,
+	.271933715484010463114,
+	.277868451003087102435,
+	.283768173130738432519,
+	.289633292582948342896,
+	.295464212893421063199,
+	.301261330578199704177,
+	.307025035294827830512,
+	.312755710004239517729,
+	.318453731118097493890,
+	.324119468654316733591,
+	.329753286372579168528,
+	.335355541920762334484,
+	.340926586970454081892,
+	.346466767346100823488,
+	.351976423156884266063,
+	.357455888922231679316,
+	.362905493689140712376,
+	.368325561158599157352,
+	.373716409793814818840,
+	.379078352934811846353,
+	.384411698910298582632,
+	.389716751140440464951,
+	.394993808240542421117,
+	.400243164127459749579,
+	.405465108107819105498,
+	.410659924985338875558,
+	.415827895143593195825,
+	.420969294644237379543,
+	.426084395310681429691,
+	.431173464818130014464,
+	.436236766774527495726,
+	.441274560805140936281,
+	.446287102628048160113,
+	.451274644139630254358,
+	.456237433481874177232,
+	.461175715122408291790,
+	.466089729924533457960,
+	.470979715219073113985,
+	.475845904869856894947,
+	.480688529345570714212,
+	.485507815781602403149,
+	.490303988045525329653,
+	.495077266798034543171,
+	.499827869556611403822,
+	.504556010751912253908,
+	.509261901790523552335,
+	.513945751101346104405,
+	.518607764208354637958,
+	.523248143765158602036,
+	.527867089620485785417,
+	.532464798869114019908,
+	.537041465897345915436,
+	.541597282432121573947,
+	.546132437597407260909,
+	.550647117952394182793,
+	.555141507540611200965,
+	.559615787935399566777,
+	.564070138285387656651,
+	.568504735352689749561,
+	.572919753562018740922,
+	.577315365035246941260,
+	.581691739635061821900,
+	.586049045003164792433,
+	.590387446602107957005,
+	.594707107746216934174,
+	.599008189645246602594,
+	.603290851438941899687,
+	.607555250224322662688,
+	.611801541106615331955,
+	.616029877215623855590,
+	.620240409751204424537,
+	.624433288012369303032,
+	.628608659422752680256,
+	.632766669570628437213,
+	.636907462236194987781,
+	.641031179420679109171,
+	.645137961373620782978,
+	.649227946625615004450,
+	.653301272011958644725,
+	.657358072709030238911,
+	.661398482245203922502,
+	.665422632544505177065,
+	.669430653942981734871,
+	.673422675212350441142,
+	.677398823590920073911,
+	.681359224807238206267,
+	.685304003098281100392,
+	.689233281238557538017,
+	.693147180560117703862
+};
+
+static double logF_tail[N+1] = {
+	0.,
+	-.00000000000000543229938420049,
+	 .00000000000000172745674997061,
+	-.00000000000001323017818229233,
+	-.00000000000001154527628289872,
+	-.00000000000000466529469958300,
+	 .00000000000005148849572685810,
+	-.00000000000002532168943117445,
+	-.00000000000005213620639136504,
+	-.00000000000001819506003016881,
+	 .00000000000006329065958724544,
+	 .00000000000008614512936087814,
+	-.00000000000007355770219435028,
+	 .00000000000009638067658552277,
+	 .00000000000007598636597194141,
+	 .00000000000002579999128306990,
+	-.00000000000004654729747598444,
+	-.00000000000007556920687451336,
+	 .00000000000010195735223708472,
+	-.00000000000017319034406422306,
+	-.00000000000007718001336828098,
+	 .00000000000010980754099855238,
+	-.00000000000002047235780046195,
+	-.00000000000008372091099235912,
+	 .00000000000014088127937111135,
+	 .00000000000012869017157588257,
+	 .00000000000017788850778198106,
+	 .00000000000006440856150696891,
+	 .00000000000016132822667240822,
+	-.00000000000007540916511956188,
+	-.00000000000000036507188831790,
+	 .00000000000009120937249914984,
+	 .00000000000018567570959796010,
+	-.00000000000003149265065191483,
+	-.00000000000009309459495196889,
+	 .00000000000017914338601329117,
+	-.00000000000001302979717330866,
+	 .00000000000023097385217586939,
+	 .00000000000023999540484211737,
+	 .00000000000015393776174455408,
+	-.00000000000036870428315837678,
+	 .00000000000036920375082080089,
+	-.00000000000009383417223663699,
+	 .00000000000009433398189512690,
+	 .00000000000041481318704258568,
+	-.00000000000003792316480209314,
+	 .00000000000008403156304792424,
+	-.00000000000034262934348285429,
+	 .00000000000043712191957429145,
+	-.00000000000010475750058776541,
+	-.00000000000011118671389559323,
+	 .00000000000037549577257259853,
+	 .00000000000013912841212197565,
+	 .00000000000010775743037572640,
+	 .00000000000029391859187648000,
+	-.00000000000042790509060060774,
+	 .00000000000022774076114039555,
+	 .00000000000010849569622967912,
+	-.00000000000023073801945705758,
+	 .00000000000015761203773969435,
+	 .00000000000003345710269544082,
+	-.00000000000041525158063436123,
+	 .00000000000032655698896907146,
+	-.00000000000044704265010452446,
+	 .00000000000034527647952039772,
+	-.00000000000007048962392109746,
+	 .00000000000011776978751369214,
+	-.00000000000010774341461609578,
+	 .00000000000021863343293215910,
+	 .00000000000024132639491333131,
+	 .00000000000039057462209830700,
+	-.00000000000026570679203560751,
+	 .00000000000037135141919592021,
+	-.00000000000017166921336082431,
+	-.00000000000028658285157914353,
+	-.00000000000023812542263446809,
+	 .00000000000006576659768580062,
+	-.00000000000028210143846181267,
+	 .00000000000010701931762114254,
+	 .00000000000018119346366441110,
+	 .00000000000009840465278232627,
+	-.00000000000033149150282752542,
+	-.00000000000018302857356041668,
+	-.00000000000016207400156744949,
+	 .00000000000048303314949553201,
+	-.00000000000071560553172382115,
+	 .00000000000088821239518571855,
+	-.00000000000030900580513238244,
+	-.00000000000061076551972851496,
+	 .00000000000035659969663347830,
+	 .00000000000035782396591276383,
+	-.00000000000046226087001544578,
+	 .00000000000062279762917225156,
+	 .00000000000072838947272065741,
+	 .00000000000026809646615211673,
+	-.00000000000010960825046059278,
+	 .00000000000002311949383800537,
+	-.00000000000058469058005299247,
+	-.00000000000002103748251144494,
+	-.00000000000023323182945587408,
+	-.00000000000042333694288141916,
+	-.00000000000043933937969737844,
+	 .00000000000041341647073835565,
+	 .00000000000006841763641591466,
+	 .00000000000047585534004430641,
+	 .00000000000083679678674757695,
+	-.00000000000085763734646658640,
+	 .00000000000021913281229340092,
+	-.00000000000062242842536431148,
+	-.00000000000010983594325438430,
+	 .00000000000065310431377633651,
+	-.00000000000047580199021710769,
+	-.00000000000037854251265457040,
+	 .00000000000040939233218678664,
+	 .00000000000087424383914858291,
+	 .00000000000025218188456842882,
+	-.00000000000003608131360422557,
+	-.00000000000050518555924280902,
+	 .00000000000078699403323355317,
+	-.00000000000067020876961949060,
+	 .00000000000016108575753932458,
+	 .00000000000058527188436251509,
+	-.00000000000035246757297904791,
+	-.00000000000018372084495629058,
+	 .00000000000088606689813494916,
+	 .00000000000066486268071468700,
+	 .00000000000063831615170646519,
+	 .00000000000025144230728376072,
+	-.00000000000017239444525614834
+};
+
+double
+#ifdef _ANSI_SOURCE
+log(double x)
+#else
+log(x) double x;
+#endif
+{
+	int m, j;
+	double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0;
+	volatile double u1;
+
+	/* Catch special cases */
+	if (x <= 0)
+		if (_IEEE && x == zero)	/* log(0) = -Inf */
+			return (-one/zero);
+		else if (_IEEE)		/* log(neg) = NaN */
+			return (zero/zero);
+		else if (x == zero)	/* NOT REACHED IF _IEEE */
+			return (infnan(-ERANGE));
+		else
+			return (infnan(EDOM));
+	else if (!finite(x))
+		if (_IEEE)		/* x = NaN, Inf */
+			return (x+x);
+		else
+			return (infnan(ERANGE));
+	
+	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
+	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
+
+	m = logb(x);
+	g = ldexp(x, -m);
+	if (_IEEE && m == -1022) {
+		j = logb(g), m += j;
+		g = ldexp(g, -j);
+	}
+	j = N*(g-1) + .5;
+	F = (1.0/N) * j + 1;	/* F*128 is an integer in [128, 512] */
+	f = g - F;
+
+	/* Approximate expansion for log(1+f/F) ~= u + q */
+	g = 1/(2*F+f);
+	u = 2*f*g;
+	v = u*u;
+	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
+
+    /* case 1: u1 = u rounded to 2^-43 absolute.  Since u < 2^-8,
+     * 	       u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits.
+     *         It also adds exactly to |m*log2_hi + log_F_head[j] | < 750
+    */
+	if (m | j)
+		u1 = u + 513, u1 -= 513;
+
+    /* case 2:	|1-x| < 1/256. The m- and j- dependent terms are zero;
+     * 		u1 = u to 24 bits.
+    */
+	else
+		u1 = u, TRUNC(u1);
+	u2 = (2.0*(f - F*u1) - u1*f) * g;
+			/* u1 + u2 = 2f/(2F+f) to extra precision.	*/
+
+	/* log(x) = log(2^m*F*(1+f/F)) =				*/
+	/* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q);	*/
+	/* (exact) + (tiny)						*/
+
+	u1 += m*logF_head[N] + logF_head[j];		/* exact */
+	u2 = (u2 + logF_tail[j]) + q;			/* tiny */
+	u2 += logF_tail[N]*m;
+	return (u1 + u2);
+}
+
+/*
+ * Extra precision variant, returning struct {double a, b;};
+ * log(x) = a+b to 63 bits, with a is rounded to 26 bits.
+ */
+struct Double
+#ifdef _ANSI_SOURCE
+__log__D(double x)
+#else
+__log__D(x) double x;
+#endif
+{
+	int m, j;
+	double F, f, g, q, u, v, u2, one = 1.0;
+	volatile double u1;
+	struct Double r;
+
+	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
+	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
+
+	m = logb(x);
+	g = ldexp(x, -m);
+	if (_IEEE && m == -1022) {
+		j = logb(g), m += j;
+		g = ldexp(g, -j);
+	}
+	j = N*(g-1) + .5;
+	F = (1.0/N) * j + 1;
+	f = g - F;
+
+	g = 1/(2*F+f);
+	u = 2*f*g;
+	v = u*u;
+	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
+	if (m | j)
+		u1 = u + 513, u1 -= 513;
+	else
+		u1 = u, TRUNC(u1);
+	u2 = (2.0*(f - F*u1) - u1*f) * g;
+
+	u1 += m*logF_head[N] + logF_head[j];
+
+	u2 +=  logF_tail[j]; u2 += q;
+	u2 += logF_tail[N]*m;
+	r.a = u1 + u2;			/* Only difference is here */
+	TRUNC(r.a);
+	r.b = (u1 - r.a) + u2;
+	return (r);
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/log10.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/log10.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <math.h>
+
+#ifndef	LN10
+#define	LN10	log(10.0)
+#endif
+
+/* Return the base-ten logarithm of X.  */
+double
+DEFUN(log10, (x), double x)
+{
+  static double ln10 = 0.0;
+
+  if (ln10 == 0.0)
+    ln10 = LN10;
+
+  return log(x) / ln10;
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/log1p.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/log1p.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log1p.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* LOG1P(x) 
+ * RETURN THE LOGARITHM OF 1+x
+ * DOUBLE PRECISION (VAX D FORMAT 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85; 
+ * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/24/85, 4/16/85.
+ * 
+ * Required system supported functions:
+ *	scalb(x,n) 
+ *	copysign(x,y)
+ *	logb(x)	
+ *	finite(x)
+ *
+ * Required kernel function:
+ *	log__L(z)
+ *
+ * Method :
+ *	1. Argument Reduction: find k and f such that 
+ *			1+x  = 2^k * (1+f), 
+ *	   where  sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ *	2. Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ *		 = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ *	   log(1+f) is computed by
+ *
+ *	     		log(1+f) = 2s + s*log__L(s*s)
+ *	   where
+ *		log__L(z) = z*(L1 + z*(L2 + z*(... (L6 + z*L7)...)))
+ *
+ *	   See log__L() for the values of the coefficients.
+ *
+ *	3. Finally,  log(1+x) = k*ln2 + log(1+f).  
+ *
+ *	Remarks 1. In step 3 n*ln2 will be stored in two floating point numbers
+ *		   n*ln2hi + n*ln2lo, where ln2hi is chosen such that the last 
+ *		   20 bits (for VAX D format), or the last 21 bits ( for IEEE 
+ *		   double) is 0. This ensures n*ln2hi is exactly representable.
+ *		2. In step 1, f may not be representable. A correction term c
+ *	 	   for f is computed. It follows that the correction term for
+ *		   f - t (the leading term of log(1+f) in step 2) is c-c*x. We
+ *		   add this correction term to n*ln2lo to attenuate the error.
+ *
+ *
+ * Special cases:
+ *	log1p(x) is NaN with signal if x < -1; log1p(NaN) is NaN with no signal;
+ *	log1p(INF) is +INF; log1p(-1) is -INF with signal;
+ *	only log1p(0)=0 is exact for finite argument.
+ *
+ * Accuracy:
+ *	log1p(x) returns the exact log(1+x) nearly rounded. In a test run 
+ *	with 1,536,000 random arguments on a VAX, the maximum observed
+ *	error was .846 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include <errno.h>
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1  ,7217,4031,0000,f7d0,   0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(sqrt2, 1.4142135623730950622E0   ,04f3,40b5,de65,33f9,   1, .B504F333F9DE65)
+
+ic(ln2hi, 6.9314718036912381649E-1,   -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76)
+ic(sqrt2, 1.4142135623730951455E0,     0, 1.6A09E667F3BCD)
+
+#ifdef vccast
+#define	ln2hi	vccast(ln2hi)
+#define	ln2lo	vccast(ln2lo)
+#define	sqrt2	vccast(sqrt2)
+#endif
+
+extern double logb(), scalb();
+
+double log1p(x)
+double x;
+{
+	const static double zero=0.0, negone= -1.0, one=1.0, 
+		      half=1.0/2.0, small=1.0E-20;   /* 1+small == 1 */
+	double z,s,t,c;
+	int k;
+
+#if !defined(vax)&&!defined(tahoe)
+	if(x!=x) return(x);	/* x is NaN */
+#endif	/* !defined(vax)&&!defined(tahoe) */
+
+	if(finite(x)) {
+	   if( x > negone ) {
+
+	   /* argument reduction */
+	      if(copysign(x,one)<small) return(x);
+	      k=logb(one+x); z=scalb(x,-k); t=scalb(one,-k);
+	      if(z+t >= sqrt2 ) 
+		  { k += 1 ; z *= half; t *= half; }
+	      t += negone; x = z + t;
+	      c = (t-x)+z ;		/* correction term for x */
+
+ 	   /* compute log(1+x)  */
+              s = x/(2+x); t = x*x*half;
+	      c += (k*ln2lo-c*x);
+	      z = c+s*(t+__log__L(s*s));
+	      x += (z - t) ;
+
+	      return(k*ln2hi+x);
+	   }
+	/* end of if (x > negone) */
+
+	    else {
+#if defined(vax)||defined(tahoe)
+		if ( x == negone )
+		    return (infnan(-ERANGE));	/* -INF */
+		else
+		    return (infnan(EDOM));	/* NaN */
+#else	/* defined(vax)||defined(tahoe) */
+		/* x = -1, return -INF with signal */
+		if ( x == negone ) return( negone/zero );
+
+		/* negative argument for log, return NaN with signal */
+	        else return ( zero / zero );
+#endif	/* defined(vax)||defined(tahoe) */
+	    }
+	}
+    /* end of if (finite(x)) */
+
+    /* log(-INF) is NaN */
+	else if(x<0) 
+	     return(zero/zero);
+
+    /* log(+INF) is INF */
+	else return(x);      
+}
--- libc-sparc-5.3.12.orig/libc/sysdeps/linux/sparc/math/log__L.c
+++ libc-sparc-5.3.12/libc/sysdeps/linux/sparc/math/log__L.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log__L.c	8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* log__L(Z)
+ *		LOG(1+X) - 2S			       X
+ * RETURN      ---------------  WHERE Z = S*S,  S = ------- , 0 <= Z <= .0294...
+ *		      S				     2 + X
+ *		     
+ * DOUBLE PRECISION (VAX D FORMAT 56 bits or IEEE DOUBLE 53 BITS)
+ * KERNEL FUNCTION FOR LOG; TO BE USED IN LOG1P, LOG, AND POW FUNCTIONS
+ * CODED IN C BY K.C. NG, 1/19/85; 
+ * REVISED BY K.C. Ng, 2/3/85, 4/16/85.
+ *
+ * Method :
+ *	1. Polynomial approximation: let s = x/(2+x). 
+ *	   Based on log(1+x) = log(1+s) - log(1-s)
+ *		 = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ *
+ *	   (log(1+x) - 2s)/s is computed by
+ *
+ *	       z*(L1 + z*(L2 + z*(... (L7 + z*L8)...)))
+ *
+ *	   where z=s*s. (See the listing below for Lk's values.) The 
+ *	   coefficients are obtained by a special Remez algorithm. 
+ *
+ * Accuracy:
+ *	Assuming no rounding error, the maximum magnitude of the approximation 
+ *	error (absolute) is 2**(-58.49) for IEEE double, and 2**(-63.63)
+ *	for VAX D format.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(L1, 6.6666666666666703212E-1 ,aaaa,402a,aac5,aaaa,  0, .AAAAAAAAAAAAC5)
+vc(L2, 3.9999999999970461961E-1 ,cccc,3fcc,2684,cccc, -1, .CCCCCCCCCC2684)
+vc(L3, 2.8571428579395698188E-1 ,4924,3f92,5782,92f8, -1, .92492492F85782)
+vc(L4, 2.2222221233634724402E-1 ,8e38,3f63,af2c,39b7, -2, .E38E3839B7AF2C)
+vc(L5, 1.8181879517064680057E-1 ,2eb4,3f3a,655e,cc39, -2, .BA2EB4CC39655E)
+vc(L6, 1.5382888777946145467E-1 ,8551,3f1d,781d,e8c5, -2, .9D8551E8C5781D)
+vc(L7, 1.3338356561139403517E-1 ,95b3,3f08,cd92,907f, -2, .8895B3907FCD92)
+vc(L8, 1.2500000000000000000E-1 ,0000,3f00,0000,0000, -2, .80000000000000)
+
+ic(L1, 6.6666666666667340202E-1, -1, 1.5555555555592)
+ic(L2, 3.9999999999416702146E-1, -2, 1.999999997FF24)
+ic(L3, 2.8571428742008753154E-1, -2, 1.24924941E07B4)
+ic(L4, 2.2222198607186277597E-1, -3, 1.C71C52150BEA6)
+ic(