diff -urN gcc-3.0.4-eelinux.orig/config.guess gcc-3.0.4-eelinux/config.guess
--- gcc-3.0.4-eelinux.orig/config.guess	Sat Jun  9 13:49:05 2001
+++ gcc-3.0.4-eelinux/config.guess	Thu Mar  7 03:47:25 2002
@@ -763,23 +763,19 @@
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit 0 ;;
     mips:Linux:*:*)
-	cat >$dummy.c <<EOF
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-int main (int argc, char *argv[]) {
-#else
-int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __MIPSEB__
-  printf ("%s-unknown-linux-gnu\n", argv[1]);
-#endif
-#ifdef __MIPSEL__
-  printf ("%sel-unknown-linux-gnu\n", argv[1]);
-#endif
-  return 0;
-}
+		sed 's/^		//'  <<EOF >$dummy.c
+		int main()
+		{
+			int x = 1;
+			return !*(char *)&x; /* Exit 1 for big-endian */
+		}
 EOF
-	$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+	$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy 
+	if test "$?" = 1 ; then
+		echo mips-unknown-linux-gnu
+	else
+		echo mipsel-unknown-linux-gnu
+	fi
 	rm -f $dummy.c $dummy
 	;;
     ppc:Linux:*:*)
diff -urN gcc-3.0.4-eelinux.orig/config.sub gcc-3.0.4-eelinux/config.sub
--- gcc-3.0.4-eelinux.orig/config.sub	Thu Jan 31 14:42:45 2002
+++ gcc-3.0.4-eelinux/config.sub	Thu Mar  7 03:47:25 2002
@@ -237,6 +237,7 @@
 		| 1750a | dsp16xx | pdp10 | pdp11 \
 		| mips16 | mips64 | mipsel | mips64el \
 		| mips64orion | mips64orionel | mipstx39 | mipstx39el \
+		| mipsEE | mipsEEel \
 		| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
 		| mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
 		| xtensa \
@@ -286,6 +287,7 @@
 	      | mips64el-* | mips64orion-* | mips64orionel-* \
 	      | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
 	      | mipstx39-* | mipstx39el-* | mcore-* \
+	      | mipsEE-* | mipsEEel-* \
 	      | xtensa-* \
 	      | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
 	      | [cjt]90-* \
@@ -923,11 +925,10 @@
 		basic_machine=hppa1.1-oki
 		;;
 	mips)
-		if [ x$os = x-linux-gnu ]; then
-			basic_machine=mips-unknown
-		else
-			basic_machine=mips-mips
-		fi
+		case x$os in
+		  x-linux*) basic_machine=mips-unknown ;;
+		  *) basic_machine=mips-mips;;
+		esac
 		;;
 	romp)
 		basic_machine=romp-ibm
diff -urN gcc-3.0.4-eelinux.orig/configure.in gcc-3.0.4-eelinux/configure.in
--- gcc-3.0.4-eelinux.orig/configure.in	Mon Aug 13 11:14:49 2001
+++ gcc-3.0.4-eelinux/configure.in	Thu Mar  7 03:47:25 2002
@@ -276,6 +276,7 @@
     alpha*-dec-osf*)	enable_shared=yes ;;
     alpha*-*-linux*)	enable_shared=yes ;;
     mips-sgi-irix5*)	enable_shared=yes ;;
+    mips*-*-linux*)	enable_shared=yes ;;
     *)			enable_shared=no ;;
   esac
 fi
diff -urN gcc-3.0.4-eelinux.orig/gcc/Makefile.in gcc-3.0.4-eelinux/gcc/Makefile.in
--- gcc-3.0.4-eelinux.orig/gcc/Makefile.in	Sun Nov 18 18:46:43 2001
+++ gcc-3.0.4-eelinux/gcc/Makefile.in	Thu Mar  7 03:47:25 2002
@@ -1079,6 +1079,7 @@
 	LIB1FUNCS_EXTRA='$(LIB1FUNCS_EXTRA)' \
 	LIB2FUNCS='$(LIB2FUNCS)' \
 	LIB2FUNCS_ST='$(LIB2FUNCS_ST)' \
+	LIB2FUNCS_TI='$(LIB2FUNCS_TI)' \
 	LIB2ADD='$(LIB2ADD)' \
 	LIB2ADDEH='$(LIB2ADDEH)' \
 	LIB2ADDEHDEP='$(LIB2ADDEHDEP)' \
diff -urN gcc-3.0.4-eelinux.orig/gcc/c-common.c gcc-3.0.4-eelinux/gcc/c-common.c
--- gcc-3.0.4-eelinux.orig/gcc/c-common.c	Thu Jan 31 18:31:52 2002
+++ gcc-3.0.4-eelinux/gcc/c-common.c	Thu Mar  7 03:47:25 2002
@@ -1842,10 +1842,8 @@
   if (mode == TYPE_MODE (intDI_type_node))
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
 
-#if HOST_BITS_PER_WIDE_INT >= 64
   if (mode == TYPE_MODE (intTI_type_node))
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
-#endif
 
   if (mode == TYPE_MODE (float_type_node))
     return float_type_node;
@@ -1896,10 +1894,8 @@
     return long_long_unsigned_type_node;
   if (type1 == widest_integer_literal_type_node)
     return widest_unsigned_literal_type_node;
-#if HOST_BITS_PER_WIDE_INT >= 64
   if (type1 == intTI_type_node)
     return unsigned_intTI_type_node;
-#endif
   if (type1 == intDI_type_node)
     return unsigned_intDI_type_node;
   if (type1 == intSI_type_node)
@@ -1931,10 +1927,8 @@
     return long_long_integer_type_node;
   if (type1 == widest_unsigned_literal_type_node)
     return widest_integer_literal_type_node;
-#if HOST_BITS_PER_WIDE_INT >= 64
   if (type1 == unsigned_intTI_type_node)
     return intTI_type_node;
-#endif
   if (type1 == unsigned_intDI_type_node)
     return intDI_type_node;
   if (type1 == unsigned_intSI_type_node)
@@ -2828,16 +2822,12 @@
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
-#if HOST_BITS_PER_WIDE_INT >= 64
   pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node));
-#endif
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
-#if HOST_BITS_PER_WIDE_INT >= 64
   pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node));
-#endif
 
   /* Create the widest literal types.  */
   widest_integer_literal_type_node
diff -urN gcc-3.0.4-eelinux.orig/gcc/config/mips/ee-perfcounter.c gcc-3.0.4-eelinux/gcc/config/mips/ee-perfcounter.c
--- gcc-3.0.4-eelinux.orig/gcc/config/mips/ee-perfcounter.c	Wed Dec 31 18:00:00 1969
+++ gcc-3.0.4-eelinux/gcc/config/mips/ee-perfcounter.c	Thu Mar  7 03:47:25 2002
@@ -0,0 +1,647 @@
+/* GCC rutime support routines for bb profiling with 
+   EE performance counter */
+
+/* Copyright (C) 2001  Sony Computer Entertainment Inc. 
+   Copyright 2001  Sony Corportaion.  */
+
+/* This file is derived from libgcc2.c and subject to the original 
+   license of libgcc2.c, as follows. */
+
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 92-98, 1999 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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+
+#include "tconfig.h"
+
+/* fixproto guarantees these system headers exist. */
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "machmode.h"
+#include "defaults.h" 
+
+#include <stdio.h>
+#include <asm/sys_r5900.h>
+
+#ifndef BB_INITAL_STACK_SIZE
+#define BB_INITAL_STACK_SIZE	10
+#endif
+#ifndef BB_GROWTH_OF_STACK_SIZE 
+#define BB_GROWTH_OF_STACK_SIZE	100
+#endif
+
+/********
+ *
+ * Basic structures for bb profiling.
+ * These definition of structures must be sync with in "libgcc2.c".
+ *
+ */
+
+/* This sttucture is used the connection to the outside world.
+   The BLOCK_PROFILER macro must set __bb.blocks
+   and __bb.blockno.  */
+
+struct __bb {
+  unsigned long blockno;
+  struct bb *blocks;
+} ;
+
+struct bb_extension {
+	char flags;
+#if  defined(BB_CONSTRUCT_PRIVATE_RECORD) \
+  || defined(BB_DESTRUCT_PRIVATE_RECORD)  \
+  || defined(BB_PRINT_PRIVATE_RECORD) 
+	void *private;
+#endif
+};
+
+/* Structure emitted by -a  */
+/* must be sync with emitting LPBX0 part 
+		of end_final() in final.c */
+struct bb
+{
+  long zero_word;
+  const char *filename;
+  long *counts;
+  long ncounts;
+  struct bb *next;
+  const unsigned long *addresses;
+
+  /* Older GCC's did not emit these fields.  */
+  long nwords;
+  const char **functions;
+  const long *line_nums;
+  const char **filenames;
+  struct bb_extension *extension;
+};
+
+enum bb_func_mode
+{
+  TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
+};
+
+/*
+ * End of basic structure definitons
+ *
+ ********/
+
+#ifdef HAVE_POPEN
+
+/*#include <sys/types.h>*/
+#include <sys/stat.h>
+/*#include <malloc.h>*/
+
+/* Commands executed by gopen.  */
+
+#define GOPENDECOMPRESS "gzip -cd "
+#define GOPENCOMPRESS "gzip -c >"
+
+/* Like fopen but pipes through gzip.  mode may only be "r" or "w".
+   If it does not compile, simply replace gopen by fopen and delete
+   '.gz' from any first parameter to gopen.  */
+
+static FILE *
+gopen (char *fn, char *mode)
+{
+  int use_gzip;
+  char *p;
+
+  if (mode[1])
+    return (FILE *) 0;
+
+  if (mode[0] != 'r' && mode[0] != 'w') 
+    return (FILE *) 0;
+
+  p = fn + strlen (fn)-1;
+  use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
+	      || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
+
+  if (use_gzip)
+    {
+      if (mode[0]=='r')
+        {
+          FILE *f;
+          char *s = (char *) malloc (sizeof (char) * strlen (fn)
+				     + sizeof (GOPENDECOMPRESS));
+          strcpy (s, GOPENDECOMPRESS);
+          strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
+          f = popen (s, mode);
+          free (s);
+          return f;
+        }
+
+      else
+        {
+          FILE *f;
+          char *s = (char *) malloc (sizeof (char) * strlen (fn)
+				     + sizeof (GOPENCOMPRESS));
+          strcpy (s, GOPENCOMPRESS);
+          strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
+          if (!(f = popen (s, mode)))
+            f = fopen (s, mode);
+          free (s);
+          return f;
+        }
+    }
+
+  else
+    return fopen (fn, mode);
+}
+
+static int
+gclose (FILE *f)
+{
+  struct stat buf;
+
+  if (f != 0)
+    {
+      if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
+        return pclose (f);
+
+      return fclose (f);
+    }
+  return 0;
+}
+
+#endif /* HAVE_POPEN */
+
+
+/*
+ * private methods & vars.
+ *
+ *
+ */
+
+static short bb_enable_perfcounter=0;
+static short bb_enable_trace_perfcounter=0;
+static struct sys_r5900_ctrs bb_last_ctrs;
+static FILE *bb_perfcountfile = (FILE *) 0;
+static struct __bb  previous_bb = {0, 0};
+
+static struct __bb  *perf_bb_stack = (struct __bb *) 0;
+static int perf_bb_stacksize = 0;
+static const struct __bb dummy_bb={0,0};
+static long perf_bb_callcount = 0;
+
+static int target[2] = { CCR_TARGET_U, CCR_TARGET_U};
+static int event[2] = {CCR_CTR0_NO_EVENT,CCR_CTR1_NO_EVENT};
+
+struct event_table {
+	int val;
+	char *name;
+};
+
+static struct  event_table counter0_event_table[] = {
+	{CCR_CTR0_CPU_CYCLE           ,   "Processor_cycle"},
+	{CCR_CTR0_SINGLE_ISSUE        ,   "Single_instructions_issue"},
+	{CCR_CTR0_BRANCH_ISSUED       ,   "Branch_issued"},
+	{CCR_CTR0_BTAC_MISS           ,   "BTAC_miss"},
+	{CCR_CTR0_TLB_MISS            ,   "TLB_miss"},
+	{CCR_CTR0_ICACHE_MISS         ,   "Instruction_cache_miss"},
+	{CCR_CTR0_DTLB_ACCESSED       ,   "DTLB_accessed"},
+	{CCR_CTR0_NONBLOCK_LOAD       ,   "Non-blocking_load"},
+	{CCR_CTR0_WBB_SINGLE_REQ      ,   "WBB_single_request"},
+	{CCR_CTR0_WBB_BURST_REQ       ,   "WBB_burst_request"},
+	{CCR_CTR0_ADDR_BUS_BUSY       ,   "CPU_address_bus_busy"},
+	{CCR_CTR0_INST_COMP           ,   "Instruction_completed"},
+	{CCR_CTR0_NON_BDS_COMP        ,   "Non-BDS_instruction_completed"},
+	{CCR_CTR0_COP2_COMP           ,   "COP2_instruction_completed"},
+	{CCR_CTR0_LOAD_COMP           ,   "Load_completed"},
+	{CCR_CTR0_NO_EVENT            ,   "No_event"},
+	{0,0}};
+
+static struct  event_table counter1_event_table[]= {
+	{CCR_CTR1_LOW_BRANCH_ISSUED   ,   "Low-order_branch_issued"},
+	{CCR_CTR1_CPU_CYCLE           ,   "Processor_cycle"},
+	{CCR_CTR1_DUAL_ISSUE          ,   "Dual_instructions_issue"},
+	{CCR_CTR1_BRANCH_MISS_PREDICT ,   "Branch_miss-predicted"},
+	{CCR_CTR1_ITLB_MISS           ,   "ITLB_miss"},
+	{CCR_CTR1_DTLB_MISS           ,   "DTLB_miss"},
+	{CCR_CTR1_DCACHE_MISS         ,   "Data_cache_miss"},
+	{CCR_CTR1_WBB_SINGLE_UNAVAIL  ,   "WBB_single_request_unavailable"},
+	{CCR_CTR1_WBB_BURST_UNAVAIL   ,   "WBB_burst_request_unavailable"},
+	{CCR_CTR1_WBB_BURST_ALMOST    ,   "WBB_burst_request_almost_full"},
+	{CCR_CTR1_WBB_BURST_FULL      ,   "WBB_burst_request_full"},
+	{CCR_CTR1_DATA_BUS_BUSY       ,   "CPU_data_bus_busy"},
+	{CCR_CTR1_INST_COMP           ,   "Instruction_completed"},
+	{CCR_CTR1_NON_BDS_COMP        ,   "Non-BDS_instruction_completed"},
+	{CCR_CTR1_COP1_COMP           ,   "COP1_instruction_completed"},
+	{CCR_CTR1_STORE_COMP          ,   "Store_completed"},
+	{CCR_CTR1_NO_EVENT            ,   "No_event"},
+	{0,0}};
+
+static struct event_table * event_selector[] = {
+	counter0_event_table,
+	counter1_event_table
+};
+
+
+
+inline
+static
+int bb_performance_counter_parser(const char *p, int perfcounter)
+{
+	int i;
+
+	i =     strlen("target:");
+	if (!strncmp(p,"target:", i) ){
+		p += i;
+		i = 0;
+		--p;
+		do {
+			p ++;
+			switch (*p) {
+			  case 'U':
+				i |=  CCR_TARGET_U;
+				break;
+			  case 'S':
+				i |=  CCR_TARGET_S;
+				break;
+			  case 'K':
+				i |=  CCR_TARGET_K;
+				break;
+			  case 'E':
+				i |=  CCR_TARGET_EXL;
+				break;
+			  default:
+				return 0;
+			}
+			p ++;
+		}
+		while ( *p == '|' );
+		target[perfcounter] = i;
+		return 1;
+	}
+	else{
+		i =     strlen("event:");
+		if (!strncmp(p,"event:", i) ){
+			struct event_table *acceptable_event = 
+				event_selector[perfcounter];
+			p += i;
+			i = 0;
+			while ( acceptable_event[i].name ) {
+				if ( !strcmp(acceptable_event[i].name, p)) {
+					event[perfcounter] = 
+						acceptable_event[i].val;
+					return 1;
+				}
+				i ++;
+			}
+			return 0;
+		}
+	}
+}
+
+inline 
+static void bb_shutdown_ctrs(void)
+{
+	int ccr;
+	ccr=0;
+	sysmips(MIPS_SYS_R5900,SYS_R5900_SET_CCR, &ccr);
+}
+
+/*
+ * return 1 if busy or fail.
+ * oterwise return 0;
+ */
+inline 
+static int bb_init_ctrs(void)
+{
+	int ccr;
+	struct sys_r5900_ctrs zero_ctrs = {0,0};
+	if (sysmips(MIPS_SYS_R5900,SYS_R5900_GET_CCR, &ccr)){
+		return 1;
+	}
+	if (CCR_GET_CTE(ccr))
+		return 1;
+	ccr = 0;
+	if ( sysmips(MIPS_SYS_R5900,SYS_R5900_SET_CCR, &ccr))
+		return 1;;
+	if (sysmips(MIPS_SYS_R5900,SYS_R5900_SET_CTRS, &zero_ctrs))
+		return 1;;
+
+	ccr = CCR_SET_CTE(ccr, 1);
+	ccr = CCR_SET_CTR0_TARGET(ccr, target[0]);
+	ccr = CCR_SET_CTR1_TARGET(ccr, target[1]);
+	ccr = CCR_SET_CTR0_EVENT(ccr, event[0]);
+	ccr = CCR_SET_CTR1_EVENT(ccr, event[1]);
+
+	return (sysmips(MIPS_SYS_R5900,SYS_R5900_SET_CCR, &ccr));
+}
+
+inline
+static int bb_get_ctrs( struct sys_r5900_ctrs *p_val)  
+{
+	return sysmips(MIPS_SYS_R5900,SYS_R5900_GET_CTRS, p_val);
+}
+
+inline 
+static void bb_delta_ctrs( 
+	struct sys_r5900_ctrs *p_dst,  
+	struct sys_r5900_ctrs *p_new,  
+	struct sys_r5900_ctrs *p_old)  
+{
+	p_dst->ctr0 = p_new->ctr0 - p_old->ctr0;
+	p_dst->ctr1 = p_new->ctr1 - p_old->ctr1;
+	p_dst->ctr0 &=  ~( (__u64) 1 << 63 );
+	p_dst->ctr1 &=  ~( (__u64) 1 << 63 );
+}
+
+
+/* bb_record_perf_count() */
+/* 	update previous_bb's perfctrs record */
+/* 	update previous_bb as given *p__bb */
+/*	record current value of perfctrs into "bbperfcount.gz" */
+/*		if trace_flag is ON */
+
+#define BB_TRACE_ON	1
+#define BB_TRACE_OFF	0
+inline
+static
+void bb_record_perf_count(const struct __bb * p__bb, int trace_flag)
+{
+	struct sys_r5900_ctrs delta_ctrs, ctrs;
+
+	/* obatin current counters */
+	bb_get_ctrs(&ctrs);
+
+	/* calc. ctrs diff */
+	bb_delta_ctrs(&delta_ctrs, &ctrs, &bb_last_ctrs);
+
+	/* update last ctrs */
+	bb_last_ctrs = ctrs;
+ 
+	if (previous_bb.blocks) {
+		register struct sys_r5900_ctrs * p_ctrs;
+		p_ctrs = previous_bb.blocks->
+				extension[previous_bb.blockno].private;
+		p_ctrs ->ctr0 += delta_ctrs.ctr0;
+		p_ctrs ->ctr1 += delta_ctrs.ctr1;
+	}
+	previous_bb = *p__bb;
+	if (!bb_perfcountfile) return;
+
+	if ( trace_flag == BB_TRACE_ON) {
+		/* write current ctrs */
+		fwrite (&ctrs, sizeof (ctrs), 1, bb_perfcountfile);
+	}
+}
+
+/*
+ * exported methods
+ *
+ *
+ */
+
+/*
+ * constructor/destructor of private record
+ */
+int __bb_alloc_r5900_perf_counter(void **p_private)
+{
+	*p_private = calloc(1, sizeof(struct sys_r5900_ctrs));
+	return ( *p_private != 0);
+};
+
+void __bb_free_r5900_perf_counter(void **p_private)
+{
+	if (*p_private) { 
+		free(*p_private); 
+		*p_private = 0;
+	}
+};
+
+
+/*
+ * reporter of private record
+ */
+void __bb_print_r5900_perf_counter(FILE *file, void *private)
+{
+	struct sys_r5900_ctrs *p_ctrs  = private;
+	if (bb_enable_perfcounter) {
+		fprintf(file," counter#0(0x%01x:0x%02x):0x%016llx", 
+			target[0],event[0], p_ctrs->ctr0);
+		fprintf(file," counter#1(0x%01x:0x%02x):0x%016llx", 
+			target[1],event[1], p_ctrs->ctr1);
+	}
+}
+
+/*
+ * parser of bb.in 
+ */
+int __bb_parse_r5900_perf_counter(const char *p)
+{
+	int i;
+	if (!strcmp(p,"enable_trace_performance_counter") ){
+		bb_enable_trace_perfcounter = 1;
+		return 1;
+	};
+	if (!strcmp(p,"enable_performance_counter") ){
+		bb_enable_perfcounter = 1;
+		return 1;
+	};
+
+	i =     strlen("performance_counter#");
+	if (!strncmp(p,"performance_counter#", i) ){
+		int perfcounter;
+		p += i;
+		perfcounter = *p -'0';
+		if (perfcounter != 0 && perfcounter != 1 ) {
+			return 0;
+		}
+		p ++;
+		if (*p != ':' ) return 0;
+		p ++;
+		
+		return bb_performance_counter_parser(p, perfcounter);
+
+	}
+	return 0;
+}
+
+/*
+ * called once per program.
+ */
+
+void __bb_init_r5900_perf_counter()
+{
+	if (bb_enable_perfcounter) {
+		perf_bb_stacksize = BB_INITAL_STACK_SIZE;
+		perf_bb_stack = (struct __bb *) malloc 
+				(perf_bb_stacksize * sizeof (struct __bb));
+		if (!perf_bb_stack)
+			perf_bb_stacksize = 0;
+
+		if (bb_init_ctrs()) {
+			/* fail or busy */
+			bb_enable_perfcounter=0;
+			bb_enable_trace_perfcounter=0;
+			return ;
+		};
+		bb_get_ctrs(&bb_last_ctrs);
+	}
+	if (bb_enable_trace_perfcounter) {
+		bb_enable_perfcounter = 1;
+#ifdef HAVE_POPEN 
+		bb_perfcountfile = gopen ("bbperfcount.gz", "w");
+#else
+		bb_perfcountfile = fopen ("bbperfcount", "w");
+#endif
+	}
+}
+
+void __bb_exit_r5900_perf_counter()
+{
+	if ( bb_enable_perfcounter ) {
+		/* record final. portion */
+		bb_record_perf_count(&dummy_bb,BB_TRACE_ON);
+		/* shutdown counter */
+		bb_shutdown_ctrs();
+	}
+	if (bb_perfcountfile) {
+#ifdef HAVE_POPEN
+		gclose (bb_perfcountfile);
+#else
+		fclose (bb_perfcountfile);
+#endif /* HAVE_POPEN */
+	}
+	if (perf_bb_stack) {
+		free (perf_bb_stack);
+		perf_bb_stack = 0;
+	}
+}
+
+
+/*
+ * called on every entering to BB.
+ */
+void __bb_trace_r5900_perf_counter(struct __bb *p__bb)
+{
+	if ( bb_enable_perfcounter ) {
+		bb_record_perf_count(p__bb, BB_TRACE_ON);
+	}
+}
+
+
+/*
+ * called on every entering to function.
+ */
+void __bb_init_trace_r5900_perf_counter
+	(struct bb *blocks, unsigned long blockno)
+{
+	static short reported = 0;
+
+	/* return if perfcounting is not enabled */
+	if ( !bb_enable_perfcounter ) {
+		return;
+	}
+
+	/* update last ovserved counter value and then return, 
+		if cannot operate previous_bb's stack.*/
+	if (perf_bb_stacksize == 0) {
+		bb_record_perf_count(&dummy_bb,BB_TRACE_OFF);
+		return;
+	}
+
+
+	if (perf_bb_callcount) {
+
+		perf_bb_callcount ++;
+
+		/* grow stack, if needed */
+		if (perf_bb_callcount >= perf_bb_stacksize) {
+			int newsize = perf_bb_callcount + 
+					BB_GROWTH_OF_STACK_SIZE;
+			perf_bb_stack = (struct __bb *) 
+				realloc (perf_bb_stack, 
+				newsize*sizeof(struct __bb));
+			if (! perf_bb_stack) {
+				if (!reported) {
+					fprintf (stderr, 
+					   "Profiler: out of memory\n");
+					reported = 1;
+				}
+				perf_bb_stacksize = 0;
+				goto stack_overflow;
+			}
+			perf_bb_stacksize = newsize;
+		}
+
+		/* push previous_bb */
+		perf_bb_stack[perf_bb_callcount] = previous_bb;
+		/* recored perfcounters in previous_bb,
+			counted before entering the function */
+		bb_record_perf_count(&dummy_bb,BB_TRACE_OFF);
+stack_overflow:
+		return;
+	}
+
+	if (blocks->extension && 
+	      (blocks->extension[blockno].flags & TRACE_ON)) {
+
+		perf_bb_callcount = 1;
+		previous_bb=dummy_bb;
+		if (perf_bb_stack)
+			perf_bb_stack[perf_bb_callcount] = previous_bb;
+
+		/* update last ovserved counter value */
+		bb_record_perf_count(&dummy_bb,BB_TRACE_OFF);
+	} 
+}
+
+/*
+ * called on every leaving from function.
+ */
+
+void __bb_ret_trace_r5900_perf_counter(void)
+{
+	if ( !bb_enable_perfcounter ) {
+		return;
+	}
+
+	if (perf_bb_callcount) {
+		if ( perf_bb_stacksize > perf_bb_callcount) {
+		/* record counters in the last part of the function 
+			and pop previous_bb, if possible */
+			bb_record_perf_count (
+				&(perf_bb_stack[perf_bb_callcount]),
+				BB_TRACE_OFF);
+		}
+		else {
+	 		/* update last observed counters,  */
+			/* if stack is overflowed. */
+			bb_record_perf_count(&dummy_bb,BB_TRACE_OFF);
+		}
+		perf_bb_callcount --;
+	}
+}
+
+void __r5900_update_ctrs(void)
+{
+	bb_get_ctrs(&bb_last_ctrs);
+}
+
+
diff -urN gcc-3.0.4-eelinux.orig/gcc/config/mips/eelinux.h gcc-3.0.4-eelinux/gcc/config/mips/eelinux.h
--- gcc-3.0.4-eelinux.orig/gcc/config/mips/eelinux.h	Wed Dec 31 18:00:00 1969
+++ gcc-3.0.4-eelinux/gcc/config/mips/eelinux.h	Thu Mar  7 03:47:25 2002
@@ -0,0 +1,251 @@
+/*
+ *
+ *
+ *
+ */
+
+/* Experimental: */
+#define MIPS_ABI_DEFAULT ABI_32
+#undef mips_abi
+extern int mips_abi;
+/* End of experimental */
+
+#define MIPS_CPU_STRING_DEFAULT "R5900"
+
+#undef  MIPS_ISA_DEFAULT
+#define MIPS_ISA_DEFAULT 2
+
+#include "linux.h"
+#include "abi64.h"
+
+/*
+ * Override TARGET_DEFAULT
+ * for r5900 : default is -msingle-float
+ */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_ABICALLS|MASK_GAS|MASK_SINGLE_FLOAT|MASK_MIPS5900)
+
+#undef MACHINE_TYPE
+#define MACHINE_TYPE "(MIPSEL EE Linux/ELF)"
+
+/* How to output a quadword for the r5900.  */
+#define ASM_OUTPUT_QUADRUPLE_INT(STREAM,VALUE)                          \
+do {                                                                    \
+  if (TARGET_64BIT)                                                     \
+    {                                                                   \
+      fprintf (STREAM, "\t.octa\t");                                    \
+      if (HOST_BITS_PER_WIDE_INT < 64 || GET_CODE (VALUE) != CONST_INT) \
+        /* We can't use 'X' for negative numbers, because then we won't \
+           get the right value for the upper 32 bits.  */               \
+        output_addr_const (STREAM, VALUE);                              \
+      else                                                              \
+        /* We must use 'X', because otherwise LONG_MIN will print as    \
+           a number that the Irix 6 assembler won't accept.  */         \
+        print_operand (STREAM, VALUE, 'X');                             \
+      fprintf (STREAM, "\n");                                           \
+    }                                                                   \
+  else                                                                  \
+    {                                                                   \
+      assemble_integer (operand_subword ((VALUE), 0, 0, TImode),        \
+                        UNITS_PER_WORD, 1);                             \
+      assemble_integer (operand_subword ((VALUE), 1, 0, TImode),        \
+                        UNITS_PER_WORD, 1);                             \
+    }                                                                   \
+} while (0)
+
+/* ALIGN 128 bit objects */
+
+#define DEFAULT_MIPS_ALIGNMENT 128
+
+#undef SUBTARGET_TARGET_OPTIONS
+#define SUBTARGET_TARGET_OPTIONS					\
+  { "align128", &mips_align128_string,					\
+      "Speciy 128bit alignment to use"},				\
+  { "no-align128", &mips_no_align128_string,				\
+      "Speciy no 128bit alignment to use"},				\
+  { "abi=", &mips_abi_string,						\
+      "Speciy ABI to use"},
+
+#undef STACK_BOUNDARY
+#define STACK_BOUNDARY							\
+  ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI)	\
+   ? 64 : 128)
+
+#undef MIPS_STACK_ALIGN
+#define MIPS_STACK_ALIGN(LOC)						\
+  (((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI)	\
+    && mips_alignment != 128 )	 					\
+   ? ((LOC) + 7) & ~7							\
+   : ((LOC) + 15) & ~15)
+
+
+#undef  BIGGEST_ALIGNMENT 
+#define BIGGEST_ALIGNMENT  mips_alignment
+
+#define PREFERRED_STACK_BOUNDARY \
+(mips_alignment == 128 ? 128 : 						\
+  ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI )	\
+   ? 64 : 128))
+
+
+/*
+
+	    ** Table of cc1 flags v.s. stack alignment related values **
+
+	STACK_BOUNDARY MIPS_STACK_ALIGN BIGGEST_ALIGNMENT  PREFERRED_STACK_BOUNDARY
+o32/o64		64		64		64		64
+ +align128	64		128		128		128
+n32/n64		128		128		64		128
+ +align128	128		128		128		128
+*/
+
+/*
+////////////
+//
+// default mips2 
+//
+// default is  elf, -mabi=o32, -mips2, -mcpu=r5900  and -EL
+*/
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "\
+-D__ELF__ -D_MIPS_SIM=_MIPS_SIM_ABI32 \
+-D_MIPS_ISA=_MIPS_ISA_MIPS2 \
+-Dunix  -D__unix__ \
+-Dlinux -D__linux__ \
+-Dmips -D_mips -D__mips -D__mips__ \
+-DR3000 -D_R3000 \
+-DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__ \
+-Asystem(linux) -Asystem(posix) -Acpu(mips) -Amachine(mips) \
+ "
+
+#undef SUBTARGET_CPP_SPEC 
+#define SUBTARGET_CPP_SPEC "\
+%{mfp32: -D_MIPS_FPSET=16}%{!mfp32: -D_MIPS_FPSET=32} \
+%{mips1: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS1} \
+%{mips2: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS2} \
+%{mips3: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS3 -UR3000 -U_R3000} \
+%{mips4: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS4 -UR3000 -U_R3000} \
+%{!mips*: -D_MIPS_ISA=_MIPS_ISA_MIPS2} \
+%{fno-PIC: -U__PIC__ -U__pic__} \
+%{fno-pic: -U__PIC__ -U__pic__} \
+%{fPIC: -D__PIC__ -D__pic__} \
+%{fpic: -D__PIC__ -D__pic__} \
+%{!fpic: %{!fPIC: %{!fno-pic: %{!fno-pic: -D__PIC__ -D__pic__}}}} \
+%{-D__HAVE_FPU__ } \
+%{posix: -D_POSIX_SOURCE} \
+%{.cc:	-D__LANGUAGE_C_PLUS_PLUS__  %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
+%{.cxx:	-D__LANGUAGE_C_PLUS_PLUS__  %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
+%{.C:	-D__LANGUAGE_C_PLUS_PLUS__  %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
+%{.m:	-D__LANGUAGE_OBJECTIVE_C__ %{!ansi:-DLANGUAGE_OBJECTIVE_C}} \
+%{.S:	-D__LANGUAGE_ASSEMBLY__ %{!ansi:-DLANGUAGE_ASSEMBLY}} \
+%{.s:	-D__LANGUAGE_ASSEMBLY__ %{!ansi:-DLANGUAGE_ASSEMBLY}} \
+%{!.S: %{!.s: %{!.cc: %{!.cxx: %{!.C: %{!.m: -D__LANGUAGE_C__ %{!ansi:-DLANGUAGE_C}}}}}} } \
+%{ansi:-Uunix -Ulinux -Umips -UR3000 -UMIPSEB -UMIPSEL} \
+%{ffast-math: -D__FAST_MATH__} \
+%{!mcpu*: -D__R5900 -D_R5900} \
+%{mcpu=r5900: -D__R5900 -D_R5900} \
+ "
+#undef SUBTARGET_CC1_SPEC
+#define SUBTARGET_CC1_SPEC "\
+%{fno-pic: -mno-abicalls} \
+ "
+
+#undef SUBTARGET_ASM_SPEC
+#define SUBTARGET_ASM_SPEC "\
+%{!mcpu*:  -mwarn-short-loop} \
+%{!mcpu*:  -mcpu=r5900} \
+%{fno-pic: -non_shared} \
+%{mno-abicalls: -non_shared} \
+%{!fno-pic: %{!mno-abicalls: -KPIC}} \
+%{!mips*: -mips2} \
+%{!mdouble-float: -msingle-float} \
+ "
+
+
+/* 
+ * Default fucntion and data alignment values for r5900 
+ */
+
+/* prefer .p2align rather than .align (gas assumed) */
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
+  if ((LOG)!=0) \
+    if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+    else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
+
+#undef DEFAULT_LOOP_ALIGN
+#undef DEFAULT_LOOP_MAX_SKIP
+#undef DEFAULT_JUMP_ALIGN
+#undef DEFAULT_JUMP_MAX_SKIP
+#undef DEFAULT_FUNCTION_ALIGN
+#undef DEFAULT_FUNCTION_MAX_SKIP
+
+#define DEFAULT_LOOP_ALIGN 3
+#define DEFAULT_LOOP_MAX_SKIP 0
+#define DEFAULT_JUMP_ALIGN 2
+#define DEFAULT_JUMP_MAX_SKIP 0
+#define DEFAULT_FUNCTION_ALIGN 3
+#define DEFAULT_FUNCTION_MAX_SKIP 0
+
+/*
+ * bb profiling extension
+ *
+ *construct/destruct private reocord in strunc bb
+ * int  BB_CONSTRUCT_PRIVATE_RECORD(void **p_private)
+ *	( return 1 if successed, otherwise return 0 )
+ * void BB_DESTRUCT_PRIVATE_RECORD(void **p_private)
+ *
+ *called from "bb.out" reporter
+ * void BB_PRINT_PRIVATE_RECORD(FILE*, void *private)
+ *
+ *called from "bb.in" parser
+ * int  BB_PARSE_PRIVATE(char *bb_in)	
+ *	( return 1 if processed, otherwise return 0 )
+ *
+ *called per once program
+ * void BB_INIT_PRIVATE(void)
+ * void BB_EXIT_PRIVATE(void)
+ *
+ *called when etering/returning function
+ * void BB_INIT_TRACE_FUNC_PRIVATE(struct bb *blocks, unsigned long blockno)
+ * void BB_TRACE_RET_PRIVATE(void)
+ *
+ *called when entering bb
+ * void BB_TRACE_FUNC_PRIVATE(struct __bb * p__bb)
+ *
+ */
+
+#define BB_CONSTRUCT_PRIVATE_RECORD(p_private)	\
+		__bb_alloc_r5900_perf_counter(p_private)
+
+#define BB_DESTRUCT_PRIVATE_RECORD(p_private)	\
+		__bb_free_r5900_perf_counter(p_private)
+
+#define BB_PRINT_PRIVATE_RECORD(file,private)	\
+		__bb_print_r5900_perf_counter(file,private)
+
+#define BB_PARSE_PRIVATE(ptr)	\
+		__bb_parse_r5900_perf_counter(ptr)
+
+#define BB_INIT_PRIVATE		\
+		__bb_init_r5900_perf_counter
+
+#define BB_EXIT_PRIVATE		\
+		__bb_exit_r5900_perf_counter
+
+#define BB_TRACE_FUNC_PRIVATE(pbb)	\
+		__bb_trace_r5900_perf_counter(pbb)
+
+#define BB_INIT_TRACE_FUNC_PRIVATE(blocks, blockno) \
+		__bb_init_trace_r5900_perf_counter(blocks, blockno)
+
+#define BB_TRACE_RET_PRIVATE \
+		__bb_ret_trace_r5900_perf_counter
+
+/*
+ * bb_stack size
+ *	inital and growth value
+ *
+ */
+#define BB_INITAL_STACK_SIZE	100
+#define BB_GROWTH_OF_STACK_SIZE	100
+
diff -urN gcc-3.0.4-eelinux.orig/gcc/config/mips/linux.h gcc-3.0.4-eelinux/gcc/config/mips/linux.h
--- gcc-3.0.4-eelinux.orig/gcc/config/mips/linux.h	Wed Aug  1 12:22:35 2001
+++ gcc-3.0.4-eelinux/gcc/config/mips/linux.h	Thu Mar  7 03:47:25 2002
@@ -28,6 +28,9 @@
 #undef MD_EXEC_PREFIX
 #undef MD_STARTFILE_PREFIX
 
+#undef HAVE_ATEXIT
+#define HAVE_ATEXIT
+
 /* Required to keep collect2.c happy */
 #undef OBJECT_FORMAT_COFF
 
@@ -35,6 +38,12 @@
 #undef TARGET_DEFAULT
 #define TARGET_DEFAULT (MASK_ABICALLS|MASK_GAS)
 
+#undef MACHINE_TYPE
+#if TARGET_ENDIAN_DEFAULT == 0
+#define MACHINE_TYPE "(MIPSEL Linux/ELF)"
+#else
+#define MACHINE_TYPE "(MIPS Linux/ELF)"
+#endif
 
 /* Handle #pragma weak and #pragma pack.  */
 #undef HANDLE_SYSV_PRAGMA
@@ -120,12 +129,29 @@
    the GNU/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'. */
+/*
+ *  Notes on STARTFILE_SPEC
+ *
+ * Glibc's  __bb_* functions produce "gmon.out", on the other hand,
+ * libgcc's __bb_* functions produce "bb.out".
+ *
+ * We expect  that "gcc -a -pg" and "gcc -a -p" produce "gmon.out" and
+ * "gcc -ax" and "gcc -a" without "-p" nor "-pg" produce "bb.out".
+ *
+ *	gcc -ax		->	... -lgcc <libc> -lgcc
+ *	gcc -a -p 	-> crt_bb_wrapper.o ...-lgcc <libc> -lgcc
+ *	gcc -a -pg 	-> crt_bb_wrapper.o ...-lgcc <libc> -lgcc
+ *	gcc -a 		->	... -lgcc <libc> -lgcc
+ *
+ * <libc> will be determined in LIBC_SPEC.
+ */
 
 #undef  STARTFILE_SPEC
 #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}"
+   crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}\
+   %{a: %{p:crt_bb_wrapper.o%s} %{pg:crt_bb_wrapper.o%s}}"
 
 /* Provide a ENDFILE_SPEC appropriate for GNU/Linux.  Here we tack on
    the GNU/Linux magical crtend.o file (see crtstuff.c) which
@@ -169,12 +195,313 @@
 %{!fno-PIC:%{!fno-pic:-KPIC}} \
 %{fno-PIC:-non_shared} %{fno-pic:-non_shared}"
 
-/* We don't need those nonsenses.  */
+/* Support the ctors and dtors sections for g++. */
+
+/* Silence GCC when using this file for the Linux libc */
+#undef CTORS_SECTION_ASM_OP
+#undef DTORS_SECTION_ASM_OP
+#define CTORS_SECTION_ASM_OP	".section\t.ctors,\"aw\""
+#define DTORS_SECTION_ASM_OP	".section\t.dtors,\"aw\""
+
+/* A default list of other sections which we might be "in" at any given
+   time.  For targets that use additional sections (e.g. .tdesc) you
+   should override this definition in the target-specific file which
+   includes this file.  */
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS in_sdata, in_sbss, in_rdata, in_ctors, in_dtors
+
+/* A default list of extra section function definitions.  For targets
+   that use additional sections (e.g. .tdesc) you should override this
+   definition in the target-specific file which includes this file.  */
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS                                         \
+  SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP) \
+  SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP) \
+  SECTION_FUNCTION_TEMPLATE(rdata_section, in_rdata, RDATA_SECTION_ASM_OP) \
+  SECTION_FUNCTION_TEMPLATE(ctors_section, in_ctors, CTORS_SECTION_ASM_OP) \
+  SECTION_FUNCTION_TEMPLATE(dtors_section, in_dtors, DTORS_SECTION_ASM_OP)
+
+/* This is the pseudo-op used to generate a 32-bit word of data with a
+   specific value in some section.  This is the same for all known svr4
+   assemblers.  */
+
+#define INT_ASM_OP		".long"
+
+/* A C statement (sans semicolon) to output an element in the table of
+   global constructors.  */
+#undef ASM_OUTPUT_CONSTRUCTOR
+#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME)				\
+  do {									\
+    ctors_section ();							\
+    fprintf (FILE, "\t%s\t ", INT_ASM_OP);				\
+    assemble_name (FILE, NAME);						\
+    fprintf (FILE, "\n");						\
+  } while (0)
+
+/* A C statement (sans semicolon) to output an element in the table of
+   global destructors.  */
+#undef ASM_OUTPUT_DESTRUCTOR
+#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME)       				\
+  do {									\
+    dtors_section ();                   				\
+    fprintf (FILE, "\t%s\t ", INT_ASM_OP);				\
+    assemble_name (FILE, NAME);              				\
+    fprintf (FILE, "\n");						\
+  } while (0)
+
+#define INIT_SECTION_ASM_OP ".section .init,\"x\""
+#define FINI_SECTION_ASM_OP ".section .fini,\"x\""
+
 #undef INVOKE__main
+
 #undef CTOR_LIST_BEGIN
+#define CTOR_LIST_BEGIN                                 \
+asm (CTORS_SECTION_ASM_OP);                             \
+static							\
+func_ptr __CTOR_LIST__[1] = { (func_ptr) (-1) }
+ 
 #undef CTOR_LIST_END
+#define CTOR_LIST_END                                   \
+asm (CTORS_SECTION_ASM_OP);                             \
+static							\
+func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
+ 
 #undef DTOR_LIST_BEGIN
+#define DTOR_LIST_BEGIN                                 \
+asm (DTORS_SECTION_ASM_OP);                             \
+static							\
+func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) }
+
 #undef DTOR_LIST_END
+#define DTOR_LIST_END                                   \
+asm (DTORS_SECTION_ASM_OP);                             \
+static							\
+func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
+
+
+/* If defined, a C expression whose value is a string containing the
+   assembler operation to identify the following data as
+   uninitialized global data.  If not defined, and neither
+   `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
+   uninitialized global data will be output in the data section if
+   `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
+   used.  */
+#undef BSS_SECTION_ASM_OP
+#define BSS_SECTION_ASM_OP      ".section\t.bss"
+
+#undef SBSS_SECTION_ASM_OP
+#define SBSS_SECTION_ASM_OP     "\t.section .sbss"
+
+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a
+   separate, explicit argument.  If you define this macro, it is used
+   in place of `ASM_OUTPUT_BSS', and gives you more flexibility in
+   handling the required alignment of the variable.  The alignment is
+   specified as the number of bits.
+
+   Try to use function `asm_output_aligned_bss' defined in file
+   `varasm.c' when defining this macro. */
+
+#undef ASM_OUTPUT_ALIGNED_BSS 
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+do {									\
+  ASM_GLOBALIZE_LABEL (FILE, NAME);					\
+  if (SIZE > 0 && SIZE <= mips_section_threshold)			\
+    sbss_section ();							\
+  else									\
+    bss_section ();							\
+  ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));		\
+  last_assemble_variable_decl = DECL;					\
+  ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);				\
+  ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1);				\
+} while (0)
+
+/* This says how to output assembler code to declare an
+   uninitialized external linkage data object.  Under SVR4,
+   the linker seems to want the alignment of data objects
+   to depend on their types.  We do exactly that here.  */
+
+#define COMMON_ASM_OP  ".comm"
+
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
+do {									\
+  fprintf ((FILE), "\t%s\t", COMMON_ASM_OP);				\
+  assemble_name ((FILE), (NAME));					\
+  fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT);	\
+} while (0)
+
+/* This says how to output assembler code to declare an
+   uninitialized internal linkage data object.  Under SVR4,
+   the linker seems to want the alignment of data objects
+   to depend on their types.  We do exactly that here.  */
+
+#define LOCAL_ASM_OP   ".local"
+
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
+do {									\
+  fprintf ((FILE), "\t%s\t", LOCAL_ASM_OP);				\
+  assemble_name ((FILE), (NAME));					\
+  fprintf ((FILE), "\n");						\
+  ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN);			\
+} while (0)
+
+/* The system header files are C++ aware. */
+#undef NO_IMPLICIT_EXTERN_C
+#define NO_IMPLICIT_EXTERN_C 1
+
+//
+// LIB_SPEC and LINK_SPEC
+//    from gcc-2.7.2 mips patch
+//
+/* 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.  */
+
+#undef LINK_SPEC
+#define LINK_SPEC "\
+%{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} %{mips4} \
+%{bestGnum} %{shared} %{non_shared} \
+%{call_shared} %{no_archive} %{exact_version} \
+  %{!shared: \
+      %{!static: \
+       %{rdynamic:-export-dynamic} \
+       %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \
+      %{static:-static}}"
+
+
+/*
+ * Notes on LIB_SPEC 
+ *
+ * Both -p and -pg will produce function profiling codes.
+ * Difference of thease is only wheather linking 
+ * static profiled libc or not.
+ *
+ *	gcc -p 		->	... -lgcc -lc_p -lgcc
+ *	gcc -pg		->	... -lgcc -lc -lgcc
+ *
+ */
+
+#undef LIB_SPEC
+#define LIB_SPEC \
+  "%{!shared: %{mieee-fp:-lieee} \
+	%{a: %{!ggdb:-lc} %{ggdb:-lg}} \
+  	%{!a: %{p:-lc_p}  \
+		%{!p: %{!ggdb:-lc} %{ggdb:-lg} } } }"
+
+
+//
+// linux/include/asm-mips/posix_types.h use pre-defined size macro
+//
+//
+
+#undef SUBTARGET_CPP_SIZE_SPEC 
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mgp64: -D_MIPS_SZPTR=64 } \
+%{!mgp64: -D_MIPS_SZPTR=32 } \
+\
+%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int \
+  -D__SSIZE_TYPE__=long\\ int \
+  -D__PTRDIFF_TYPE__=long\\ int \
+  -D_MIPS_SZLONG=64}  \
+\
+%{mint64:-D_MIPS_SZINT=64 \
+  %{!mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int \
+    -D__SSIZE_TYPE__=long\\ int \
+    -D__PTRDIFF_TYPE__=long\\ int \
+    -D_MIPS_SZLONG=64}} \
+\
+%{!mint64:-D_MIPS_SZINT=32 \
+  %{!mlong64:-D__SIZE_TYPE__=unsigned\\ int \
+    -D__SSIZE_TYPE__=int \
+    -D__PTRDIFF_TYPE__=int \
+    -D_MIPS_SZLONG=32}} \
+" \
+
+/* assume "-mips1 & -fPIC " is default */
+#undef SUBTARGET_CPP_SPEC 
+#define SUBTARGET_CPP_SPEC "\
+%{mfp32: -D_MIPS_FPSET=16}%{!mfp32: -D_MIPS_FPSET=32} \
+%{mips1: -D_MIPS_ISA=_MIPS_ISA_MIPS1} \
+%{mips2: -D_MIPS_ISA=_MIPS_ISA_MIPS2} \
+%{mips3: -D_MIPS_ISA=_MIPS_ISA_MIPS3} \
+%{mips4: -D_MIPS_ISA=_MIPS_ISA_MIPS4} \
+%{!mips*: -D_MIPS_ISA=_MIPS_ISA_MIPS1} \
+%{fno-PIC: -U__PIC__ -U__pic__} \
+%{fno-pic: -U__PIC__ -U__pic__} \
+%{fPIC: -D__PIC__ -D__pic__} \
+%{fpic: -D__PIC__ -D__pic__} \
+%{!fpic: %{!fPIC: %{!fno-pic: %{!fno-pic: -D__PIC__ -D__pic__}}}} \
+%{-D__HAVE_FPU__ } \
+%{posix: -D_POSIX_SOURCE} \
+%{.cc:	-D__LANGUAGE_C_PLUS_PLUS__  %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
+%{.cxx:	-D__LANGUAGE_C_PLUS_PLUS__  %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
+%{.C:	-D__LANGUAGE_C_PLUS_PLUS__  %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
+%{.m:	-D__LANGUAGE_OBJECTIVE_C__ %{!ansi:-DLANGUAGE_OBJECTIVE_C}} \
+%{.S:	-D__LANGUAGE_ASSEMBLY__ %{!ansi:-DLANGUAGE_ASSEMBLY}} \
+%{.s:	-D__LANGUAGE_ASSEMBLY__ %{!ansi:-DLANGUAGE_ASSEMBLY}} \
+%{!.S: %{!.s: %{!.cc: %{!.cxx: %{!.C: %{!.m: -D__LANGUAGE_C__ %{!ansi:-DLANGUAGE_C}}}}}} } \
+%{ansi: -Uunix -Ulinux -Umips -UR3000 -UMIPSEB -UMIPSEL} \
+ "
+
+
+// assume
+// 	TARGET_DEFAULT includes MASK_ABICALLS|GAS_MASK
+// if MASK_ABICALLS is given , pic-flag is also on.
+
+#undef SUBTARGET_ASM_SPEC
+#define SUBTARGET_ASM_SPEC "\
+%{fno-pic: -non_shared} \
+%{mno-abicalls: -non_shared} \
+%{!fno-pic: %{!mno-abicalls: -KPIC}} \
+ "
+
+#undef SUBTARGET_CC1_SPEC 
+#define SUBTARGET_CC1_SPEC "\
+%{fno-pic: -mno-abicalls} \
+ "
+
+
+#if (TARGET_ENDIAN_DEFAULT == 0)
+
+// default is  elf, -mabi=o32, -mips1 and -EL
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "\
+-D__ELF__ -D_MIPS_SIM=_MIPS_SIM_ABI32 \
+-Dunix  -D__unix__ \
+-Dlinux -D__linux__ \
+-Dmips -D_mips -D__mips -D__mips__ \
+-DR3000 -D_R3000 \
+-DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__ \
+-Asystem=linux -Asystem=posix -Acpu=mips -Amachine=mips \
+ "
+
+
+#else
+// default is  elf, -mabi=o32, -mips1 and -EB
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "\
+-D__ELF__ -D_MIPS_SIM=_MIPS_SIM_ABI32 \
+-Dunix  -D__unix__ \
+-Dlinux -D__linux__ \
+-Dmips -D_mips -D__mips -D__mips__ \
+-DR3000 -D_R3000 \
+-DMIPSEB -D_MIPSEB -D__MIPSEB -D__MIPSEB__ \
+-Asystem=linux -Asystem=posix -Acpu=mips -Amachine=mips \
+ "
+
+#endif
+
 
 /* The MIPS assembler has different syntax for .set. We set it to
    .dummy to trap any errors.  */
@@ -189,9 +516,6 @@
     fprintf (FILE, "%sLM%d:\n\t%s 68,0,%d,%sLM%d",			\
 	     LOCAL_LABEL_PREFIX, sym_lineno, ASM_STABN_OP,		\
 	     LINE, LOCAL_LABEL_PREFIX, sym_lineno);			\
-    putc ('-', FILE);							\
-    assemble_name (FILE,						\
-		   XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
     putc ('\n', FILE);							\
     sym_lineno++;							\
   }									\
@@ -253,7 +577,15 @@
    pseudo-ops.  */
 #define FUNCTION_NAME_ALREADY_DECLARED
 
+#define IDENT_ASM_OP ".ident"
+
 /* Output #ident as a .ident.  */
 #undef ASM_OUTPUT_IDENT
 #define ASM_OUTPUT_IDENT(FILE, NAME) \
   fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME);
+
+/* produce compressed bbtrace */
+#ifndef HAVE_POPEN
+#define HAVE_POPEN
+#endif
+
diff -urN gcc-3.0.4-eelinux.orig/gcc/config/mips/mips-bb-helper.asm gcc-3.0.4-eelinux/gcc/config/mips/mips-bb-helper.asm
--- gcc-3.0.4-eelinux.orig/gcc/config/mips/mips-bb-helper.asm	Wed Dec 31 18:00:00 1969
+++ gcc-3.0.4-eelinux/gcc/config/mips/mips-bb-helper.asm	Thu Mar  7 03:47:25 2002
@@ -0,0 +1,242 @@
+/* Copyright (C) 2001  Sony Computer Entertainment Inc. */
+/* Copyright 2001  Sony Corportaion. */
+
+/* This file is subject to the terms and conditions of the GNU General 
+   Public License version 2. See the file "COPYING" in the main directory 
+   of this archive for more details.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+
+
+/*
+ * BLOCK PROFILER helper functions
+ *
+ */
+	.text
+	.set noat
+
+ 	REG_SIZE = 4
+	OFF_A0 = REG_SIZE * 7
+	OFF_A1 = REG_SIZE * 8
+	OFF_A2 = REG_SIZE * 9
+	OFF_A3 = REG_SIZE * 10
+	OFF_AT = REG_SIZE * 11
+	OFF_V0 = REG_SIZE * 12
+	OFF_V1 = REG_SIZE * 13
+	OFF_FP = REG_SIZE * 14
+	OFF_T0 = REG_SIZE * 15
+	OFF_T1 = REG_SIZE * 16
+	OFF_T2 = REG_SIZE * 17
+	OFF_T3 = REG_SIZE * 18
+	OFF_T4 = REG_SIZE * 19
+	OFF_T5 = REG_SIZE * 20
+	OFF_T6 = REG_SIZE * 21
+	OFF_T7 = REG_SIZE * 22
+	OFF_T8 = REG_SIZE * 23
+
+	OFF_HI = REG_SIZE * 24
+	OFF_LO = REG_SIZE * 25
+	
+/*
+ *
+ */
+
+	  .align	2;
+	  .globl	__bb_mips_save_regs_sw
+	  .ent  	__bb_mips_save_regs_sw
+__bb_mips_save_regs_sw:
+
+	/*"$28"	/*gp: 4*/
+	/*"$31"	/*ra: 5*/
+	/*"$25"	/*t9: 6*/
+
+	sw	$4,  OFF_A0($29)	/*a0: 7*/ 
+	sw	$5,  OFF_A1($29)	/*a1: 8*/ 
+	sw	$6,  OFF_A2($29)	/*a2: 9*/ 
+	sw	$7,  OFF_A3($29)	/*a3: 10*/ 
+	sw	$1,  OFF_AT($29)	/*at: 11*/
+	sw	$2,  OFF_V0($29)	/*v0: 12*/ 
+	sw	$3,  OFF_V1($29)	/*v1: 13*/
+	sw	$30, OFF_FP($29)	/*fp: 14*/
+	sw	$8,  OFF_T0($29)	/*t0: 15*/
+	sw	$9,  OFF_T1($29)	/*t1: 16*/
+	sw	$10, OFF_T2($29)	/*t2: 17*/
+	sw	$11, OFF_T3($29)	/*t3: 18*/
+	sw	$12, OFF_T4($29)	/*t4: 19*/
+	sw	$13, OFF_T5($29)	/*t5: 20*/
+	sw	$14, OFF_T6($29)	/*t6: 21*/
+	sw	$15, OFF_T7($29)	/*t7: 22*/
+	sw	$24, OFF_T8($29)	/*t8: 23*/
+	
+
+	mfhi	$4
+	sw	$4,  OFF_HI($29)	/*hi: 24*/
+	mflo	$4
+	sw	$4,  OFF_LO($29)	/*lo: 25*/
+	j	$31
+	nop
+	.size	__bb_mips_save_regs_sw, .- __bb_mips_save_regs_sw;
+	.end	__bb_mips_save_regs_sw
+
+
+/*
+ *
+ */
+
+	.align	2
+	.globl	__bb_mips_restore_regs_lw
+	.ent	__bb_mips_restore_regs_lw
+__bb_mips_restore_regs_lw:
+
+	lw	$4,  OFF_HI($29)	/*hi: 25*/
+	mthi	$4
+	lw	$4,  OFF_LO($29)	/*lo: 26*/
+	mtlo	$4
+
+	lw	$4,  OFF_A0($29)	/*a0: 7*/ 
+	lw	$5,  OFF_A1($29)	/*a1: 8*/ 
+	lw	$6,  OFF_A2($29)	/*a2: 9*/ 
+	lw	$7,  OFF_A3($29)	/*a3: 10*/ 
+	lw	$1,  OFF_AT($29)	/*at: 11*/
+	lw	$2,  OFF_V0($29)	/*v0: 12*/ 
+	lw	$3,  OFF_V1($29)	/*v1: 13*/
+	lw	$30, OFF_FP($29)	/*fp: 14*/
+	lw	$8,  OFF_T0($29)	/*t0: 15*/
+	lw	$9,  OFF_T1($29)	/*t1: 16*/
+	lw	$10, OFF_T2($29)	/*t2: 17*/
+	lw	$11, OFF_T3($29)	/*t3: 18*/
+	lw	$12, OFF_T4($29)	/*t4: 19*/
+	lw	$13, OFF_T5($29)	/*t5: 20*/
+	lw	$14, OFF_T6($29)	/*t6: 21*/
+	lw	$15, OFF_T7($29)	/*t7: 22*/
+	lw	$24, OFF_T8($29)	/*t8: 23*/
+	
+	
+	j	$31
+	nop
+	/*"$28"	/*gp: 4*/
+	/*"$31"	/*ra: 5*/
+	/*"$25"	/*t9: 6*/
+	.size	__bb_mips_restore_regs_lw, .- __bb_mips_restore_regs_lw;
+	.end	__bb_mips_restore_regs_lw
+
+
+
+/*
+ *
+ */
+ 	REG_SIZE = 8
+	OFF_A0 = REG_SIZE * 7
+	OFF_A1 = REG_SIZE * 8
+	OFF_A2 = REG_SIZE * 9
+	OFF_A3 = REG_SIZE * 10
+	OFF_AT = REG_SIZE * 11
+	OFF_V0 = REG_SIZE * 12
+	OFF_V1 = REG_SIZE * 13
+	OFF_FP = REG_SIZE * 14
+	OFF_T0 = REG_SIZE * 15
+	OFF_T1 = REG_SIZE * 16
+	OFF_T2 = REG_SIZE * 17
+	OFF_T3 = REG_SIZE * 18
+	OFF_T4 = REG_SIZE * 19
+	OFF_T5 = REG_SIZE * 20
+	OFF_T6 = REG_SIZE * 21
+	OFF_T7 = REG_SIZE * 22
+	OFF_T8 = REG_SIZE * 23
+
+	OFF_HI = REG_SIZE * 24
+	OFF_LO = REG_SIZE * 25
+	
+
+	mfhi	$4
+	sd	$4,  OFF_HI($29)	/*hi: 24*/
+	mflo	$4
+	sd	$4,  OFF_LO($29)	/*lo: 25*/
+	  .align	2;
+	  .globl	__bb_mips_save_regs_sd
+	  .ent  	__bb_mips_save_regs_sd
+__bb_mips_save_regs_sd:
+	.set	push
+	.set	mips3
+	/*"$28"	/*gp: 4*/
+	/*"$31"	/*ra: 5*/
+	/*"$25"	/*t9: 6*/
+
+	sd	$4,  OFF_A0($29)	/*a0: 7*/ 
+	sd	$5,  OFF_A1($29)	/*a1: 8*/ 
+	sd	$6,  OFF_A2($29)	/*a2: 9*/ 
+	sd	$7,  OFF_A3($29)	/*a3: 10*/ 
+	sd	$1,  OFF_AT($29)	/*at: 11*/
+	sd	$2,  OFF_V0($29)	/*v0: 12*/ 
+	sd	$3,  OFF_V1($29)	/*v1: 13*/
+	sd	$30, OFF_FP($29)	/*fp: 14*/
+	sd	$8,  OFF_T0($29)	/*t0: 15*/
+	sd	$9,  OFF_T1($29)	/*t1: 16*/
+	sd	$10, OFF_T2($29)	/*t2: 17*/
+	sd	$11, OFF_T3($29)	/*t3: 18*/
+	sd	$12, OFF_T4($29)	/*t4: 19*/
+	sd	$13, OFF_T5($29)	/*t5: 20*/
+	sd	$14, OFF_T6($29)	/*t6: 21*/
+	sd	$15, OFF_T7($29)	/*t7: 22*/
+	sd	$24, OFF_T8($29)	/*t8: 23*/
+	
+
+	mfhi	$4
+	sd	$4,  OFF_HI($29)	/*hi: 24*/
+	mflo	$4
+	sd	$4,  OFF_LO($29)	/*lo: 25*/
+	j	$31
+	nop
+	.set	pop
+	.size	__bb_mips_save_regs_sd, .- __bb_mips_save_regs_sd;
+	.end	__bb_mips_save_regs_sd
+
+
+
+/*
+ *
+ */
+	.align	2
+	.globl	__bb_mips_restore_regs_ld
+	.ent	__bb_mips_restore_regs_ld
+__bb_mips_restore_regs_ld:
+	.set	push
+	.set	mips3
+
+
+	ld	$4,  OFF_HI($29)	/*hi: 25*/
+	mthi	$4
+	ld	$4,  OFF_LO($29)	/*lo: 26*/
+	mtlo	$4
+
+	ld	$4,  OFF_A0($29)	/*a0: 7*/ 
+	ld	$5,  OFF_A1($29)	/*a1: 8*/ 
+	ld	$6,  OFF_A2($29)	/*a2: 9*/ 
+	ld	$7,  OFF_A3($29)	/*a3: 10*/ 
+	ld	$1,  OFF_AT($29)	/*at: 11*/
+	ld	$2,  OFF_V0($29)	/*v0: 12*/ 
+	ld	$3,  OFF_V1($29)	/*v1: 13*/
+	ld	$30, OFF_FP($29)	/*fp: 14*/
+	ld	$8,  OFF_T0($29)	/*t0: 15*/
+	ld	$9,  OFF_T1($29)	/*t1: 16*/
+	ld	$10, OFF_T2($29)	/*t2: 17*/
+	ld	$11, OFF_T3($29)	/*t3: 18*/
+	ld	$12, OFF_T4($29)	/*t4: 19*/
+	ld	$13, OFF_T5($29)	/*t5: 20*/
+	ld	$14, OFF_T6($29)	/*t6: 21*/
+	ld	$15, OFF_T7($29)	/*t7: 22*/
+	ld	$24, OFF_T8($29)	/*t8: 23*/
+	
+	
+	j	$31
+	nop
+	.set	pop
+	.size	__bb_mips_restore_regs_ld, .- __bb_mips_restore_regs_ld;
+	.end	__bb_mips_restore_regs_ld
+
diff -urN gcc-3.0.4-eelinux.orig/gcc/config/mips/mips.c gcc-3.0.4-eelinux/gcc/config/mips/mips.c
--- gcc-3.0.4-eelinux.orig/gcc/config/mips/mips.c	Tue Feb 19 17:16:53 2002
+++ gcc-3.0.4-eelinux/gcc/config/mips/mips.c	Thu Mar  7 03:47:45 2002
@@ -234,6 +234,40 @@
    set this option if such an option is used. */
 const char *mips_explicit_type_size_string;
 
+/* Specify power of two alignment for loop starts, labels after barriers
+   and functions.  Also specify maximum fill/skip allowed to achieve those
+   alignments (in bytes).
+
+   These are strings filled in by the generic code with the user arguments,
+   they are parsed in OVERRIDE_OPTIONS, then never referenced again.  */
+char *mips_align_loops_string;
+char *mips_max_skip_loops_string;
+char *mips_align_jumps_string;
+char *mips_max_skip_jumps_string;
+char *mips_align_funcs_string;
+char *mips_max_skip_funcs_string;
+
+/* Specify power of two alignment for loop starts, labels after barriers
+   and functions.  Also specify maximum fill/skip allowed to achieve those
+   alignments (in bytes).
+
+   Once the above strings are parsed, the resulting values are placed in
+   these variables.  */
+int mips_align_loops;
+int mips_max_skip_loops;
+int mips_align_jumps;
+int mips_max_skip_jumps;
+int mips_align_funcs;
+int mips_max_skip_funcs;
+
+#ifdef DEFAULT_MIPS_ALIGNMENT
+int mips_alignment=DEFAULT_MIPS_ALIGNMENT;	/* biggest alignment bits */
+#else
+int mips_alignment=BIGGEST_ALIGNMENT;		/* biggest alignment bits */
+#endif
+const char * mips_no_align128_string;
+const char * mips_align128_string;
+
 /* Whether we are generating mips16 hard float code.  In mips16 mode
    we always set TARGET_SOFT_FLOAT; this variable is nonzero if
    -msoft-float was not specified by the user, which means that we
@@ -325,7 +359,7 @@
  "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
  "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
  "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
- "hi",   "lo",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
+ "lo",   "hi",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
  "$fcc5","$fcc6","$fcc7","$rap"
 };
 
@@ -342,7 +376,7 @@
   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
   "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
-  "hi",   "lo",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
+  "lo",   "hi",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
   "$fcc5","$fcc6","$fcc7","$rap"
 };
 
@@ -365,7 +399,7 @@
   FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
   FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
   FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
-  HI_REG,	LO_REG,		HILO_REG,	ST_REGS,
+  LO_REG,	HI_REG,		HILO_REG,	ST_REGS,
   ST_REGS,	ST_REGS,	ST_REGS,	ST_REGS,
   ST_REGS,	ST_REGS,	ST_REGS,	GR_REGS
 };
@@ -3904,6 +3938,20 @@
       cum->arg_words += (TARGET_64BIT ? 1 : 2);
       break;
 
+    case TImode:
+      if (!TARGET_ARG128BIT) {
+	      /* TImode arg will be splited into 2 or 4 reg */
+	      cum->gp_reg_found = 1;
+	      cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
+				 / UNITS_PER_WORD);
+	      break;
+      }
+      /* The r5900 only may need a single general register to pass a
+       TImode value.  */
+      cum->gp_reg_found = 1;
+      cum->arg_words += 1;
+      break;
+
     case QImode:
     case HImode:
     case SImode:
@@ -4024,6 +4072,18 @@
       if (! TARGET_64BIT)
 	cum->arg_words += (cum->arg_words & 1);
       regbase = GP_ARG_FIRST;
+
+    case TImode:
+      if (!TARGET_ARG128BIT) {
+	      /* TImode arg will be splited into 2 or 4 reg */
+	      regbase = GP_ARG_FIRST;
+	      break;
+      }
+      /* The r5900 only may need a single general register to pass a
+       TImode value.  */
+      regbase = GP_ARG_FIRST;
+      break;
+
     }
 
   if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
@@ -4178,6 +4238,7 @@
      int named ATTRIBUTE_UNUSED;/* != 0 for normal args, == 0 for ... args */
 {
   if ((mode == BLKmode
+       || (mode == TImode && !TARGET_ARG128BIT)
        || GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
        || GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
       && cum->arg_words < (unsigned) MAX_ARGS_IN_REGISTERS
@@ -4815,9 +4876,11 @@
 	  || mips_abi == ABI_64))
     target_flags |= MASK_LONG64;
 
+#if MIPS_ABI_DEFAULT != ABI_32
   /* ??? This doesn't work yet, so don't let people try to use it.  */
   if (mips_abi == ABI_32)
     error ("The -mabi=32 support does not work yet.");
+#endif
 
 #else
   if (mips_abi_string)
@@ -4938,6 +5001,12 @@
 	}
     }
 
+  /* set target flag for r3900, r5400 and r5900 */
+  target_flags &= ~MASK_MIPS5900;
+
+  if (mips_arch == PROCESSOR_R5900)
+      target_flags |= MASK_MIPS5900;
+
   if (mips_abi != ABI_32 && mips_abi != ABI_O64)
     flag_pcc_struct_return = 0;
 
@@ -5124,7 +5193,13 @@
 	    temp = ((regno & 1) == 0 || size <= UNITS_PER_WORD);
 
 	  else if (FP_REG_P (regno))
-	    temp = ((TARGET_FLOAT64 || ((regno & 1) == 0))
+	    /*
+	     * Use odd FP regs for TARGET_SINGLE_FLOAT even if !TARGET_FLOAT64.
+	     * TARGET_SINGLE_FLOAT means the target FPU has 32 single precision
+	     * 32bit FP regs. In this case,  FP regs aren't coupled for double 
+	     * precision, and odd FP regs can be used to compute.
+	     */
+	    temp = ((TARGET_FLOAT64 || TARGET_SINGLE_FLOAT || ((regno & 1) == 0))
 		    && (class == MODE_FLOAT
 			|| class == MODE_COMPLEX_FLOAT
 			|| (TARGET_DEBUG_H_MODE && class == MODE_INT))
@@ -5147,6 +5222,100 @@
      initialized yet, so we can't use that here.  */
   gpr_mode = TARGET_64BIT ? DImode : SImode;
 
+  {
+    int min_align = 2;
+    int max_align = 15;
+    int min_max_skip = 0;
+    int max_max_skip = 32767;
+
+    /* Validate -malign-loops= value, or provide default */
+    if (mips_align_loops_string)
+      {
+	if (TARGET_MIPS16)
+	  error ("the combination of -mips16 and -malign-loops is not supported");
+	mips_align_loops = atoi (mips_align_loops_string);
+	if (mips_align_loops < min_align || mips_align_loops > max_align)
+	  error ("-malign-loops=%d is not between %d and %d",
+	         mips_align_loops, min_align, max_align);
+      }
+    else
+      {
+	if (TARGET_MIPS16)
+	  mips_align_loops = 0;
+	else
+	  mips_align_loops = DEFAULT_LOOP_ALIGN;
+      }
+
+    /* Validate -malign-jumps= value, or provide default */
+    if (mips_align_jumps_string)
+      {
+	mips_align_jumps = atoi (mips_align_jumps_string);
+	if (mips_align_jumps < min_align || mips_align_jumps > max_align)
+	  error ("-malign-jumps=%d is not between %d and %d",
+	         mips_align_jumps, min_align, min_align);
+      }
+    else
+      mips_align_jumps = DEFAULT_JUMP_ALIGN;
+
+    /* Validate -malign-functions= value, or provide default */
+    if (mips_align_funcs_string)
+      {
+	mips_align_funcs = atoi (mips_align_funcs_string);
+	if (mips_align_funcs < min_align || mips_align_funcs > max_align)
+	  error ("-malign-functions=%d is not between %d and %d",
+	         mips_align_funcs, min_align, max_align);
+      }
+    else
+      mips_align_funcs = DEFAULT_FUNCTION_ALIGN;
+
+    /* Validate -mmax-skip-loops= value, or provide default */
+    if (mips_max_skip_loops_string)
+      {
+	mips_max_skip_loops = atoi (mips_max_skip_loops_string);
+	if (mips_max_skip_loops < min_max_skip
+	    || mips_max_skip_loops > max_max_skip)
+	  error ("-mmax-skip-loops=%d is not between %d and %d",
+		 mips_max_skip_loops, min_max_skip, max_max_skip);
+      }
+    else
+      mips_max_skip_loops = DEFAULT_LOOP_MAX_SKIP;
+
+    /* Validate -mmax-skip-jumps= value, or provide default */
+    if (mips_max_skip_jumps_string)
+      {
+	mips_max_skip_jumps = atoi (mips_max_skip_jumps_string);
+	if (mips_max_skip_jumps < min_max_skip
+	    || mips_max_skip_jumps > max_max_skip)
+	  error ("-mmax-skip-jumps=%d is not between %d and %d",
+		 mips_max_skip_jumps, min_max_skip, max_max_skip);
+      }
+    else
+      mips_max_skip_jumps = DEFAULT_JUMP_MAX_SKIP;
+
+    /* Validate -mmax-skip-functions= value, or provide default */
+    if (mips_max_skip_funcs_string)
+      {
+	mips_max_skip_funcs = atoi (mips_max_skip_funcs_string);
+	if (mips_max_skip_funcs < min_max_skip
+	    || mips_max_skip_funcs > max_max_skip)
+	  error ("-mmax-skip-functions=%d is not between %d and %d",
+		 mips_max_skip_funcs, min_max_skip, max_max_skip);
+      }
+    else
+      mips_max_skip_funcs = DEFAULT_FUNCTION_MAX_SKIP;
+  }
+
+#ifdef DEFAULT_MIPS_ALIGNMENT
+  if (mips_align128_string != NULL) {
+	/* -malign128 */
+  	mips_alignment=128;
+  } 
+  if (mips_no_align128_string != NULL) {
+	/* -mno-align128 */
+  	mips_alignment=64;
+  }
+#endif
+
   /* Provide default values for align_* for 64-bit targets.  */
   if (TARGET_64BIT && !TARGET_MIPS16)
     {
@@ -6801,7 +6970,8 @@
 #endif
   long tsize = current_frame_info.total_size;
 
-  ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE (current_function_decl));
+  /* ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE
+   * (current_function_decl)); */
 
 #ifdef SDB_DEBUGGING_INFO
   if (debug_info_level != DINFO_LEVEL_TERSE && write_symbols == SDB_DEBUG)
@@ -9119,6 +9289,216 @@
   return NULL_RTX;
 }
 
+/* On the R5900, we must ensure that the compiler never generates loops
+   that satisfy all of the following conditions:
+   
+   * a loop consists of less than equal to six instructions(includes
+     branch delay slot).
+   
+   * a loop contains only one conditional branch instruction at the
+     end of the loop.
+     
+   * a loop does not contain any other branch or jump instructions.
+
+   * a branch delay slot of the loop is not nop. ( EE#2.9 or later )
+
+   We need to do this because of a bug in the chip.
+
+   */
+/* turn FILL_BDSLOT_WITH_NOP on for EE#2.9 or later */
+#define FILL_BDSLOT_WITH_NOP
+
+#ifdef FILL_BDSLOT_WITH_NOP
+inline
+static int is_nop_insn(insn)
+	rtx insn;
+{
+	return (rtx_equal_p (insn, gen_nop ()));
+}
+#endif
+
+enum sequence_type {Jump, Reset, Otherwise};
+
+/* Detect if possible loop jump presents in the sequence */
+static enum sequence_type 
+detect_sequence_type (insn, count_p, jump_insn_p, seen_before, 
+			after_delayed_branch_sched)
+	rtx insn;
+	int *count_p;
+	rtx *jump_insn_p;
+	int *seen_before;
+	int after_delayed_branch_sched;
+{
+      int i;
+      int detect_later=0;
+
+      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+	{
+	  rtx v_insn;
+	  v_insn = XVECEXP (PATTERN (insn), 0, i);
+	  switch (GET_CODE (v_insn))
+	    {
+	    case CODE_LABEL:
+	      seen_before [INSN_UID (v_insn)] = *count_p;
+	      break;
+	    case INSN:
+	      /* The attr_length may be bigger than acctual insn length.
+	    	 So don't use it in the after_delayed_branch_sched phase. */
+	      *count_p  += ( get_attr_length (insn) > 0 
+	            		&& !after_delayed_branch_sched ) 
+			    ?  get_attr_length (insn) : 4 ; 
+	      if (detect_later) {
+		/* inspect BD slot */
+#ifdef FILL_BDSLOT_WITH_NOP
+		if (is_nop_insn (PATTERN (v_insn)))
+	            return  Reset;
+#endif
+	        return  Jump;
+	      }
+	      break;
+	    case JUMP_INSN:
+	      *jump_insn_p = v_insn;
+	      detect_later = 1;
+	      break;
+	    case CALL_INSN:
+	      return  Reset;
+	      break;
+            default: break;
+	    }
+	}
+      if (detect_later) 
+        {
+	  /* No insn presents in BD slot. AS will fill it with nop. */
+	  return  Reset;
+        }
+      return Otherwise;
+}
+
+static void
+mips_r5900_lengthen_loops (first, after_delayed_branch_sched)
+  rtx first;
+  int after_delayed_branch_sched;
+{
+  rtx insn;
+  rtx this_jump_insn;
+  const int hazardous_distance = 6;
+  int n = 4;
+  int max_uid = get_max_uid ();
+  int *seen_before = alloca (sizeof seen_before[0] * max_uid);
+  int in_sequence = 0;
+  enum sequence_type result;
+      
+  bzero ((char *) seen_before, sizeof seen_before[0] * max_uid);
+      
+  for (insn = first; insn; insn = NEXT_INSN (insn))
+    {
+      in_sequence = 0;
+      switch (GET_CODE (insn))
+	{
+	case CODE_LABEL:
+	  seen_before [INSN_UID (insn)] = n;
+	  break;
+
+	case INSN:
+	  if (GET_CODE (PATTERN (insn)) != SEQUENCE ) 
+	    {
+	      /* The attr_length may be bigger than acctual insn length.
+	         So don't use it in the after_delayed_branch_sched phase. */
+	      n += ( get_attr_length (insn) > 0 
+	            && !after_delayed_branch_sched ) 
+		 ?  get_attr_length (insn) : 4 ; 
+	      break;
+	    }
+	  result = detect_sequence_type(insn, &n, &this_jump_insn, 
+				  seen_before, after_delayed_branch_sched);
+	  switch(result) 
+	    {
+	    case Reset:
+	      goto reset;
+	      break;
+	    case Jump:
+	      in_sequence=1;
+	      goto jump_insn;
+	      break;
+	    }
+	  break;
+
+	case JUMP_INSN:
+          this_jump_insn = insn;
+	  in_sequence=0;
+        jump_insn:
+	  if (condjump_p (this_jump_insn))
+	    {
+	      rtx target = condjump_label (this_jump_insn);
+
+	      if (seen_before [INSN_UID (XEXP (target, 0))])
+		{
+		  int distance 
+		    = (n - seen_before [INSN_UID (XEXP (target, 0))]) >> 2;
+
+#ifdef FILL_BDSLOT_WITH_NOP
+		  if (!in_sequence) 
+		    {
+		    /* try to insert one nop before jump 
+		     * if distance is in hazardous_distance */
+
+	 	    if  ( distance <=  hazardous_distance )
+		      {
+		        rtx prev_insn = PREV_INSN (this_jump_insn);
+		        while ( prev_insn && ( GET_CODE (prev_insn) != INSN ))
+			    prev_insn =  PREV_INSN (prev_insn);
+			if (prev_insn && ! is_nop_insn (PATTERN (prev_insn)))
+			      emit_insn_before (gen_nop (), this_jump_insn);
+
+		      }
+		    }
+		  else 
+		    {
+		      if ( distance <= hazardous_distance ) 
+		        {
+	     	          for (; distance <= hazardous_distance; distance++) 
+		            emit_insn_before (gen_nop(), insn);
+		        }
+		    }
+#else
+		  for (; distance <= hazardous_distance; distance++)
+		    {
+		      if (after_delayed_branch_sched)
+		        emit_insn_before (gen_nop(), insn);
+		      else
+		        emit_insn_before (gen_nop_internal (), insn);
+		    }
+#endif
+		}
+	    }
+
+	  /* Falls through */
+
+	case CALL_INSN:
+	reset:
+	  bzero ((char *) seen_before, sizeof seen_before[0] * max_uid);
+	  break;
+	    
+	default:
+	  break;
+	}
+    }
+}
+ 
+/* Exported to toplev.c.
+
+   Do a final pass over the function, just before rtl to asm conversion
+   (after "delayed branch scheduling" and "shorten jump").  */
+
+void
+machine_dependent_reorg_final (first)
+     rtx first;
+{
+	if (TARGET_MIPS5900 &&  !TARGET_NO_LENGTHEN_LOOP)
+		mips_r5900_lengthen_loops (first,1);
+}
+
+
 /* Exported to toplev.c.
 
    Do a final pass over the function, just before delayed branch
@@ -9135,6 +9515,13 @@
   if (! TARGET_MIPS16)
     return;
 
+#ifdef FILL_BDSLOT_WITH_NOP
+/* To lengthen short loop should be done 
+		after "delayed branch scheduling" again */
+  if (TARGET_MIPS5900 &&  !TARGET_NO_LENGTHEN_LOOP)
+    mips_r5900_lengthen_loops (first,0);
+#endif
+
   /* If $gp is used, try to remove stores, and replace loads with
      copies from $gp.  */
   if (optimize)
@@ -9437,22 +9824,30 @@
 	{
 	case GTU:
 	  code = NE;
+          comp = "ne";
+          inverted_comp = "eq";
 	  break;
 
 	case LEU:
 	  code = EQ;
+          comp = "eq";
+          inverted_comp = "ne";
 	  break;
 
 	case GEU:
 	  /* A condition which will always be true.  */
 	  code = EQ;
 	  op1 = "%.";
+          comp = "eq";
+          inverted_comp = "ne";
 	  break;
 
 	case LTU:
 	  /* A condition which will always be false. */
 	  code = NE;
 	  op1 = "%.";
+          comp = "ne";
+          inverted_comp = "eq";
 	  break;
 
 	default:
@@ -9717,6 +10112,8 @@
     case '5':
       if (!strcmp (p, "5000") || !strcmp (p, "5k") || !strcmp (p, "5K"))
         cpu = PROCESSOR_R5000;
+      else if (!strcmp (p, "5900"))
+        cpu = PROCESSOR_R5900;
       break;
 
     case '6':
@@ -9743,3 +10140,4 @@
 
   return cpu;
 }
+
diff -urN gcc-3.0.4-eelinux.orig/gcc/config/mips/mips.h gcc-3.0.4-eelinux/gcc/config/mips/mips.h
--- gcc-3.0.4-eelinux.orig/gcc/config/mips/mips.h	Tue Feb 19 17:16:53 2002
+++ gcc-3.0.4-eelinux/gcc/config/mips/mips.h	Thu Mar  7 03:47:45 2002
@@ -67,6 +67,7 @@
   PROCESSOR_R4600,
   PROCESSOR_R4650,
   PROCESSOR_R5000,
+  PROCESSOR_R5900,
   PROCESSOR_R8000
 };
 
@@ -162,6 +163,9 @@
 extern struct rtx_def *embedded_pic_fnaddr_rtx;	/* function address */
 extern int mips_string_length;		/* length of strings for mips16 */
 extern struct rtx_def *mips16_gp_pseudo_rtx; /* psuedo reg holding $gp */
+extern int mips_alignment;			/* max alignment bits */
+extern const char * mips_align128_string;	/* for -malign128 */
+extern const char * mips_no_align128_string;	/* for -mno-align128 */
 
 /* Functions to change what output section we are using.  */
 extern void		rdata_section PARAMS ((void));
@@ -217,8 +221,15 @@
 #define MASK_UNINIT_CONST_IN_RODATA \
 			   0x01000000	/* Store uninitialized
 					   consts in rodata */
+#define MASK_MIPS5900	   0x02000000	/* r5900 port */
 
 					/* Debug switches, not documented */
+
+#define MASK_NO_LENGTHEN_LOOP 0x10000000 /* Disable r5900 legthen loop */
+#define MASK_ARG128BIT	0x20000000	/* Use r5900's 128bit gp reg 
+							for TImode arg */
+#define MASK_5900REG_CODE 0x40000000	/* Generate r5900 specfic reg code */
+
 #define MASK_DEBUG	0		/* unused */
 #define MASK_DEBUG_A	0		/* don't allow <label>($reg) addrs */
 #define MASK_DEBUG_B	0		/* GO_IF_LEGITIMATE_ADDRESS debug */
@@ -245,6 +256,18 @@
 /* generate mips 3900 insns */
 #define TARGET_MIPS3900         (target_flags & MASK_MIPS3900)
 
+/* Generate mips 5900 instructions.  */
+#define TARGET_MIPS5900		(target_flags & MASK_MIPS5900)
+
+/* Disable r5900 lengthen loop */
+#define	TARGET_NO_LENGTHEN_LOOP	(target_flags & MASK_NO_LENGTHEN_LOOP)
+
+/* Generate mips 5900 spcific regs instructions.: not yet implemented  */
+#define GENERATE_MIPS5900_REG_CODE (target_flags & MASK_5900REG_CODE)
+
+/* Pass TImode value use 128bit gp reg. : not yet implemented */
+#define TARGET_ARG128BIT	(target_flags & MASK_ARG128BIT)
+
 					/* Mips vs. GNU assembler */
 #define TARGET_GAS		(target_flags & MASK_GAS)
 #define TARGET_MIPS_AS		(!TARGET_GAS)
@@ -430,6 +453,8 @@
      N_("Optimize for 4650")},						\
   {"3900",		  MASK_MIPS3900,				\
      N_("Optimize for 3900")},						\
+  {"5900",		  MASK_MIPS5900,				\
+     "Optimize for 5900"},						\
   {"check-zero-division",-MASK_NO_CHECK_ZERO_DIV,			\
      N_("Trap on integer divide by zero")},				\
   {"no-check-zero-division", MASK_NO_CHECK_ZERO_DIV,			\
@@ -458,6 +483,8 @@
      NULL},								\
   {"debugi",		  MASK_DEBUG_I,					\
      NULL},								\
+  {"no-lengthen-loop",	  MASK_NO_LENGTHEN_LOOP,			\
+     "Disable lengthen loop for r5900"},				\
   {"",			  (TARGET_DEFAULT				\
 			   | TARGET_CPU_DEFAULT				\
 			   | TARGET_ENDIAN_DEFAULT),			\
@@ -573,6 +600,12 @@
       N_("Use mips16 entry/exit psuedo ops")},				\
   { "no-mips16", &mips_no_mips16_string,				\
       N_("Don't use MIPS16 instructions")},				\
+  { "align-loops=",	&mips_align_loops_string },			\
+  { "align-jumps=",	&mips_align_jumps_string },			\
+  { "align-functions=",	&mips_align_funcs_string },			\
+  { "max-skip-loops=",	&mips_max_skip_loops_string },			\
+  { "max-skip-jumps=",	&mips_max_skip_jumps_string },			\
+  { "max-skip-functions=",	&mips_max_skip_funcs_string },		\
   { "explicit-type-size", &mips_explicit_type_size_string,		\
       NULL},								\
 }
@@ -580,11 +613,13 @@
 /* This is meant to be redefined in the host dependent files.  */
 #define SUBTARGET_TARGET_OPTIONS
 
-#define GENERATE_BRANCHLIKELY  (!TARGET_MIPS16 && (TARGET_MIPS3900 || ISA_HAS_BRANCHLIKELY))
+#define GENERATE_BRANCHLIKELY  (!TARGET_MIPS16 && (TARGET_MIPS3900 	\
+				|| TARGET_MIPS5900 || (mips_isa >= 2)))
 
 /* Generate three-operand multiply instructions for both SImode and DImode.  */
-#define GENERATE_MULT3         (TARGET_MIPS3900				\
-				&& !TARGET_MIPS16)
+#define GENERATE_MULT3         ((TARGET_MIPS3900				\
+				 || TARGET_MIPS5900)				\
+ 				&& !TARGET_MIPS16)
 
 /* Macros to decide whether certain features are available or not,
    depending on the instruction set architecture level.  */
@@ -604,7 +639,7 @@
 				 )
 
 /* ISA has just the integer condition move instructions (movn,movz) */
-#define ISA_HAS_INT_CONDMOVE     0
+#define ISA_HAS_INT_CONDMOVE     (TARGET_MIPS5900)
 
 
 
@@ -791,7 +826,7 @@
 /* GAS_ASM_SPEC is passed when using gas, rather than the MIPS
    assembler.  */
 
-#define GAS_ASM_SPEC "%{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{v} %{mgp32} %{mgp64}"
+#define GAS_ASM_SPEC "%{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{m5900} %{v} %{mgp32} %{mgp64}"
 
 /* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or
    GAS_ASM_SPEC as the default, depending upon the value of
@@ -1391,7 +1426,8 @@
 #define PARM_BOUNDARY (TARGET_64BIT ? 64 : 32)
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
-#define FUNCTION_BOUNDARY 32
+#define FUNCTION_BOUNDARY (1 << (mips_align_funcs + 3))
+#define FUNCTION_BOUNDARY_MAX_SKIP (mips_max_skip_funcs)
 
 /* Alignment of field after `int : 0' in a structure.  */
 #define EMPTY_FIELD_BOUNDARY 32
@@ -1407,6 +1443,51 @@
    when given unaligned data.  */
 #define STRICT_ALIGNMENT 1
 
+/* Align loop starts for optimal branching.  */
+#define LOOP_ALIGN(LABEL) (mips_align_loops)
+#define LOOP_ALIGN_MAX_SKIP (mips_max_skip_loops)
+
+/* This is how to align an instruction for optimal branching. */
+#define LABEL_ALIGN_AFTER_BARRIER(LABEL) (mips_align_jumps)
+#define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP (mips_max_skip_jumps)
+
+#ifndef DEFAULT_LOOP_ALIGN
+#define DEFAULT_LOOP_ALIGN 2
+#endif
+
+#ifndef DEFAULT_JUMP_ALIGN
+#define DEFAULT_JUMP_ALIGN 2
+#endif
+
+#ifndef DEFAULT_FUNCTION_ALIGN
+#define DEFAULT_FUNCTION_ALIGN 2
+#endif
+
+#ifndef DEFAULT_LOOP_MAX_SKIP
+#define DEFAULT_LOOP_MAX_SKIP 0
+#endif
+
+#ifndef DEFAULT_JUMP_MAX_SKIP
+#define DEFAULT_JUMP_MAX_SKIP 0
+#endif
+
+#ifndef DEFAULT_FUNCTION_MAX_SKIP
+#define DEFAULT_FUNCTION_MAX_SKIP 0
+#endif
+
+extern char *mips_align_loops_string;
+extern char *mips_align_jumps_string;
+extern char *mips_align_funcs_string;
+extern int mips_align_loops;
+extern int mips_align_jumps;
+extern int mips_align_funcs;
+extern char *mips_max_skip_loops_string;
+extern char *mips_max_skip_jumps_string;
+extern char *mips_max_skip_funcs_string;
+extern int mips_max_skip_loops;
+extern int mips_max_skip_jumps;
+extern int mips_max_skip_funcs;
+
 /* Define this if you wish to imitate the way many other C compilers
    handle alignment of bitfields and the structures that contain
    them.
@@ -1593,8 +1674,8 @@
 #define RAP_REG_NUM   75
 
 #define AT_REGNUM	(GP_REG_FIRST + 1)
-#define HI_REGNUM	(MD_REG_FIRST + 0)
-#define LO_REGNUM	(MD_REG_FIRST + 1)
+#define LO_REGNUM	(MD_REG_FIRST + 0)
+#define HI_REGNUM	(MD_REG_FIRST + 1)
 #define HILO_REGNUM	(MD_REG_FIRST + 2)
 
 /* FPSW_REGNUM is the single condition code used if mips_isa < 4.  If
@@ -1771,12 +1852,12 @@
   M16_T_REGS,			/* mips16 registers plus T register */
   GR_REGS,			/* integer registers */
   FP_REGS,			/* floating point registers */
-  HI_REG,			/* hi register */
   LO_REG,			/* lo register */
+  HI_REG,			/* hi register */
   HILO_REG,			/* hilo register pair for 64 bit mode mult */
   MD_REGS,			/* multiply/divide registers (hi/lo) */
-  HI_AND_GR_REGS,		/* union classes */
   LO_AND_GR_REGS,
+  HI_AND_GR_REGS,		/* union classes */
   HILO_AND_GR_REGS,
   ST_REGS,			/* status registers (fp status) */
   ALL_REGS,			/* all registers */
@@ -1800,12 +1881,12 @@
   "M16_T_REGS",								\
   "GR_REGS",								\
   "FP_REGS",								\
-  "HI_REG",								\
   "LO_REG",								\
+  "HI_REG",								\
   "HILO_REG",								\
   "MD_REGS",								\
-  "HI_AND_GR_REGS",							\
   "LO_AND_GR_REGS",							\
+  "HI_AND_GR_REGS",							\
   "HILO_AND_GR_REGS",							\
   "ST_REGS",								\
   "ALL_REGS"								\
@@ -1831,8 +1912,8 @@
   { 0x010300fc, 0x00000000, 0x00000000 },	/* mips16 and T regs */ \
   { 0xffffffff, 0x00000000, 0x00000000 },	/* integer registers */	\
   { 0x00000000, 0xffffffff, 0x00000000 },	/* floating registers*/	\
-  { 0x00000000, 0x00000000, 0x00000001 },	/* hi register */	\
-  { 0x00000000, 0x00000000, 0x00000002 },	/* lo register */	\
+  { 0x00000000, 0x00000000, 0x00000001 },	/* lo register */	\
+  { 0x00000000, 0x00000000, 0x00000002 },	/* hi register */	\
   { 0x00000000, 0x00000000, 0x00000004 },	/* hilo register */	\
   { 0x00000000, 0x00000000, 0x00000003 },	/* mul/div registers */	\
   { 0xffffffff, 0x00000000, 0x00000001 },	/* union classes */     \
@@ -2057,11 +2138,14 @@
 #define CLASS_UNITS(mode, size)						\
   ((GET_MODE_SIZE (mode) + (size) - 1) / (size))
 
+/* If TARGET_SINGLE_FLOAT, FP regs aren't coupled odd-even pair. */
 #define CLASS_MAX_NREGS(CLASS, MODE)					\
   ((CLASS) == FP_REGS							\
    ? (TARGET_FLOAT64							\
       ? CLASS_UNITS (MODE, 8)						\
-      : 2 * CLASS_UNITS (MODE, 8))					\
+        : ( TARGET_SINGLE_FLOAT						\
+            ? CLASS_UNITS (MODE, 4)					\
+      : 2 * CLASS_UNITS (MODE, 8)))					\
    : CLASS_UNITS (MODE, UNITS_PER_WORD))
 
 /* If defined, gives a class of registers that cannot be used as the
@@ -2601,13 +2685,14 @@
   fprintf (FILE, "\t.set\tnoat\n");					\
   fprintf (FILE, "\tmove\t%s,%s\t\t# save current return address\n",	\
 	   reg_names[GP_REG_FIRST + 1], reg_names[GP_REG_FIRST + 31]);	\
-  fprintf (FILE, "\tjal\t_mcount\n");					\
   fprintf (FILE,							\
 	   "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from  stack\n",	\
 	   TARGET_64BIT ? "dsubu" : "subu",				\
 	   reg_names[STACK_POINTER_REGNUM],				\
 	   reg_names[STACK_POINTER_REGNUM],				\
 	   Pmode == DImode ? 16 : 8);					\
+  fprintf (FILE, "\tjal\t_mcount\n");					\
+  fprintf (FILE, "\tnop\n");						\
   fprintf (FILE, "\t.set\treorder\n");					\
   fprintf (FILE, "\t.set\tat\n");					\
 }
@@ -3504,6 +3589,8 @@
 	return COSTS_N_INSNS (17);					\
       else if (mips_tune == PROCESSOR_R5000)				\
 	return COSTS_N_INSNS (5);					\
+      else if (mips_tune == PROCESSOR_R5900)				\
+	return (xmode == SImode ? COSTS_N_INSNS (3) : COSTS_N_INSNS (30));\
       else								\
 	return COSTS_N_INSNS (10);					\
     }									\
@@ -3545,6 +3632,8 @@
       return COSTS_N_INSNS (38);					\
     else if (mips_tune == PROCESSOR_R5000)				\
       return COSTS_N_INSNS (36);					\
+    else if (mips_tune == PROCESSOR_R5900)				\
+      return COSTS_N_INSNS (30);					\
     else								\
       return COSTS_N_INSNS (69);					\
 									\
@@ -3697,6 +3786,9 @@
 #define ADJUST_INSN_LENGTH(INSN, LENGTH) \
   ((LENGTH) = mips_adjust_insn_length ((INSN), (LENGTH)))
 
+/* The r5900 is a dual issue machine.  */
+#undef ISSUE_RATE
+#define ISSUE_RATE ((TARGET_MIPS5900) ? 2 : 1)
 
 /* Optionally define this if you have added predicates to
    `MACHINE.c'.  This macro is called within an initializer of an
@@ -3906,7 +3998,7 @@
   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",	\
   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",	\
   "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",	\
-  "hi",   "lo",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",	\
+  "lo",   "hi",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",	\
   "$fcc5","$fcc6","$fcc7","$rap"					\
 }
 
@@ -4382,6 +4474,13 @@
 #define ASM_OUTPUT_ALIGN(STREAM,LOG)					\
   fprintf (STREAM, "\t.align\t%d\n", (LOG))
 
+#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
+  if ((LOG)!=0) \
+    if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+    else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
+#endif
+
 /* This is how to output an assembler line to advance the location
    counter by SIZE bytes.  */
 
@@ -4625,6 +4724,9 @@
 /* In mips16 mode, we need to look through the function to check for
    PC relative loads that are out of range.  */
 #define MACHINE_DEPENDENT_REORG(X) machine_dependent_reorg (X)
+
+/* For r5900, we need to lenghten short loop */
+#define MACHINE_DEPENDENT_REORG_FINAL(X) machine_dependent_reorg_final (X)
 
 /* We need to use a special set of functions to handle hard floating
    point code in mips16 mode.  */
diff -urN gcc-3.0.4-eelinux.orig/gcc/config/mips/mips.md gcc-3.0.4-eelinux/gcc/config/mips/mips.md
--- gcc-3.0.4-eelinux.orig/gcc/config/mips/mips.md	Tue Feb 19 17:16:53 2002
+++ gcc-3.0.4-eelinux/gcc/config/mips/mips.md	Thu Mar  7 03:47:25 2002
@@ -78,11 +78,12 @@
 ;; fcmp		floating point compare
 ;; fcvt		floating point convert
 ;; fsqrt	floating point square root
+;; frsqrt	floating point square root
 ;; multi	multiword sequence (or user asm statements)
 ;; nop		no operation
 
 (define_attr "type"
-  "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
+  "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
   (const_string "unknown"))
 
 ;; Main data type used by the insn
@@ -119,7 +120,7 @@
 
 ;; ??? Fix everything that tests this attribute.
 (define_attr "cpu"
-  "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
+  "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r5900,r8000"
   (const (symbol_ref "mips_cpu_attr")))
 
 ;; Does the instruction have a mandatory delay slot?
@@ -190,7 +191,7 @@
 
 (define_function_unit "memory" 1 0
   (and (eq_attr "type" "load")
-       (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
+       (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000,r5900"))
   3 0)
 
 (define_function_unit "memory" 1 0
@@ -198,17 +199,20 @@
        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
   2 0)
 
-(define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
+(define_function_unit "memory"   1 0
+  (and (eq_attr "type" "store") (eq_attr "cpu" "!r5900")) 1 0) ; pattern-sanitize-r5900-2
 
-(define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
+(define_function_unit "memory"   1 0
+  (and (eq_attr "type" "xfer") (eq_attr "cpu" "!r5900")) 2 0) ; pattern-sanitize-r5900-2
 
-(define_function_unit "imuldiv"  1 0
-  (eq_attr "type" "hilo")
-  1 3)
+ (define_function_unit "imuldiv"  1 0
+  (and (eq_attr "type" "hilo")
+       (eq_attr "cpu" "!r5900")) ; pattern-sanitize-r5900-2
+   1 3)
 
 (define_function_unit "imuldiv"  1 0
   (and (eq_attr "type" "imul")
-       (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
+       (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000,r5900"))
   17 17)
 
 ;; On them mips16, we want to stronly discourage a mult from appearing
@@ -260,7 +264,7 @@
 
 (define_function_unit "imuldiv"  1 0
   (and (eq_attr "type" "idiv")
-       (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
+       (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000,r5900"))
   38 38)
 
 (define_function_unit "imuldiv"  1 0
@@ -317,7 +321,7 @@
 ;; instructions to be processed in the "imuldiv" unit.
 
 (define_function_unit "adder" 1 1
-  (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
+  (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000,r5900"))
   3 0)
 
 (define_function_unit "adder" 1 1
@@ -329,7 +333,7 @@
   1 0)
 
 (define_function_unit "adder" 1 1
-  (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
+  (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5900"))
   4 0)
 
 (define_function_unit "adder" 1 1
@@ -342,7 +346,7 @@
 
 (define_function_unit "adder" 1 1
   (and (eq_attr "type" "fabs,fneg")
-       (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
+       (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000,r5900"))
   2 0)
 
 (define_function_unit "adder" 1 1
@@ -352,7 +356,7 @@
 (define_function_unit "mult" 1 1
   (and (eq_attr "type" "fmul")
        (and (eq_attr "mode" "SF")
-	    (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
+	    (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000,r5900")))
   7 0)
 
 (define_function_unit "mult" 1 1
@@ -388,7 +392,7 @@
 (define_function_unit "divide" 1 1
   (and (eq_attr "type" "fdiv")
        (and (eq_attr "mode" "SF")
-	    (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
+	    (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000,r5900")))
   23 0)
 
 (define_function_unit "divide" 1 1
@@ -434,33 +438,33 @@
 
 ;;; ??? Is this number right?
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fsqrt")
-       (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
+  (and (eq_attr "type" "fsqrt,frsqrt") ; CYGNUS LOCAL vr5400/raeburn
+       (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000,r5900"))) ; pattern-sanitize-r5900-1  CYGNUS LOCAL vr5400/raeburn
   54 0)
 
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fsqrt")
+  (and (eq_attr "type" "fsqrt,frsqrt")
        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
   31 0)
 
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fsqrt")
+  (and (eq_attr "type" "fsqrt,frsqrt")
        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
   21 0)
 
 ;;; ??? Is this number right?
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fsqrt")
+  (and (eq_attr "type" "fsqrt,frsqrt")
        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
   112 0)
 
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fsqrt")
+  (and (eq_attr "type" "fsqrt,frsqrt")
        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
   60 0)
 
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fsqrt")
+  (and (eq_attr "type" "fsqrt,frsqrt")
        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
   36 0)
 
@@ -483,13 +487,67 @@
   8 8)
 
 (define_function_unit "imuldiv" 1 0
-  (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
+  (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
   29 29)
 (define_function_unit "imuldiv" 1 0
-  (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
+  (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
   58 58)
+
+;; Using a value immediately after a load causes a one cycle delay.
+(define_function_unit "memory" 1 0
+  (and (eq_attr "type" "load") (eq_attr "cpu" "r5900")) 2 0)
+
+;; The r5900 has a store buffer which can cause an interlock for
+;; consecutive stores in some cases.  So try to separate stores.
+(define_function_unit "memory"   1 0
+  (and (eq_attr "type" "store") (eq_attr "cpu" "r5900"))  2 1)
+
+;; Transfer to/from coprocessor.  This is just a guess.  There may or
+;; may not be an interlock for such transfers.
+(define_function_unit "memory"   1 0
+  (and (eq_attr "type" "xfer") (eq_attr "cpu" "r5900"))  2 0)
+
+;; The r5900 has two independent ALUs.
+(define_function_unit "alu" 2 0
+  (and (eq_attr "type" "move,arith,darith,icmp,nop,branch,jump,call")
+       (eq_attr "cpu" "r5900")) 1 0)
+
+;; XXX There is differing data between the architecture manual
+;; about what these values should be.
+(define_function_unit "r5900imuldiv" 2 0
+  (and (eq_attr "type" "hilo") (eq_attr "cpu" "r5900")) 1 3)
+
+(define_function_unit "r5900imuldiv" 2 0
+  (and (eq_attr "type" "imul") (eq_attr "cpu" "r5900")) 4 2)
+
+(define_function_unit "r5900imuldiv" 2 0
+  (and (eq_attr "type" "idiv") (eq_attr "cpu" "r5900")) 37 37)
+
+;; The r5900 FP unit has three independent units.
+;; fmac  -- all computational instructions except fdiv, fsqrt, rsqrt
+;; fdiv  -- fdiv, fsqrt, rsqrt
+;; load/store -- load store and transfer unit
+;;
+;; It appears that fmac/fdiv can dual issue with load/store.
+(define_function_unit "fmac" 1 0
+  (and (eq_attr "type" "fadd,fmul,fmadd,fabs,fneg,fcmp,fcvt")
+       (eq_attr "cpu" "r5900")) 3 0)
+
+(define_function_unit "fdiv" 1 1
+  (and (eq_attr "type" "fdiv,fsqrt,frsqrt") (eq_attr "cpu" "r5900")) 6 0)
+  
+;; And now a few fake units to encourage dual issue.
+;; We can only issue one operation to the FPU per cycle.
+(define_function_unit "flop" 1 0
+  (and (eq_attr "type"
+		 "fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,xfer")
+       (eq_attr "cpu" "r5900")) 1 0)
+
+;; I don't think we need any other fake units to describe common
+;; cases.
+
 
 ;; The following functional units do not use the cpu type, and use
 ;; much less memory in genattrtab.c.
@@ -514,8 +572,45 @@
 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
 ;;
-;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
-;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
+;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt,frsqrt") (eq_attr "mode" "SF"))  54 0)
+;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt,frsqrt") (eq_attr "mode" "DF")) 112 0)
+
+;;
+;;  ....................
+;;
+;;     MIN, MAX
+;;
+;;  ....................
+
+;; minsf3
+(define_insn "minsf3"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+	(if_then_else (lt:SF
+		(match_operand:SF 1 "register_operand" "f")
+		(match_operand:SF 2 "register_operand" "f"))
+	(match_dup 1)
+	(match_dup 2)))]
+  "TARGET_HARD_FLOAT && TARGET_MIPS5900"
+  "min.s\\t%0,%1,%2"
+  [(set_attr "type"    "fadd")
+   (set_attr "mode"    "SF")
+   (set_attr "length"  "1")])
+
+;; maxsf3
+(define_insn "maxsf3"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+	(if_then_else (gt:SF
+		(match_operand:SF 1 "register_operand" "f")
+		(match_operand:SF 2 "register_operand" "f"))
+	(match_dup 1)
+	(match_dup 2)))]
+  "TARGET_HARD_FLOAT && TARGET_MIPS5900"
+  "max.s\\t%0,%1,%2"
+  [(set_attr "type"    "fadd")
+   (set_attr "mode"    "SF")
+   (set_attr "length"  "1")])
+
+
 
 ;;
 ;;  ....................
@@ -1727,7 +1822,8 @@
    (clobber (match_scratch:SI 3 "=h,h"))
    (clobber (match_scratch:SI 4 "=l,X"))
    (clobber (match_scratch:SI 5 "=a,a"))]
-  "GENERATE_MULT3
+  "(GENERATE_MULT3 && !TARGET_MIPS5900)
+   || (GENERATE_MULT3 && TARGET_MIPS5900 && !GENERATE_MIPS5900_REG_CODE)
    || TARGET_MAD"
   "*
 {
@@ -1795,7 +1891,8 @@
    (clobber (match_scratch:SI 5 "=X,3,l"))
    (clobber (match_scratch:SI 6 "=a,a,a"))
    (clobber (match_scratch:SI 7 "=X,X,d"))]
-  "TARGET_MIPS3900
+  "(TARGET_MIPS3900
+   || (TARGET_MIPS5900 && !GENERATE_MIPS5900_REG_CODE))
    && !TARGET_MIPS16"
   "*
 {
@@ -1855,7 +1952,9 @@
 
   "
 {
-  if (GENERATE_MULT3 || mips_arch == PROCESSOR_R4000 || TARGET_MIPS16)
+  if ((GENERATE_MULT3 && !TARGET_MIPS5900 )
+   || mips_arch == PROCESSOR_R4000 || TARGET_MIPS16
+   || (GENERATE_MULT3 && TARGET_MIPS5900 && !GENERATE_MIPS5900_REG_CODE ))
     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
   else
     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
@@ -2096,11 +2195,17 @@
 			   [(match_operand:SI 2 "register_operand" "d")]))
 		 (match_dup 0)))
    (clobber (match_scratch:SI 5 "=a"))]
-  "TARGET_MAD
+  "(TARGET_MAD
+   || (TARGET_MIPS5900 && !GENERATE_MIPS5900_REG_CODE ))
    && ! TARGET_64BIT
    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
   "*
 {
+  if (TARGET_MIPS5900 && !GENERATE_MIPS5900_REG_CODE )
+    if (GET_CODE (operands[3]) == SIGN_EXTEND)
+      return \"madd\\t%1,%2\";
+    else
+      return \"maddu\\t%1,%2\";
   if (GET_CODE (operands[3]) == SIGN_EXTEND)
     return \"mad\\t%1,%2\";
   else
@@ -2236,9 +2341,17 @@
 	(div:SF (match_operand:SF 1 "register_operand" "f")
 		(match_operand:SF 2 "register_operand" "f")))]
   "TARGET_HARD_FLOAT"
-  "div.s\\t%0,%1,%2"
+  "*
+  if (TARGET_MIPS5900)
+    return (\"%(nop\;nop\;div.s\\t%0,%1,%2%)\");
+  return(\"div.s\\t%0,%1,%2\");
+  "
   [(set_attr "type"	"fdiv")
-   (set_attr "mode"	"SF")])
+   (set_attr "mode"	"SF")
+   (set (attr "length") 
+   	(if_then_else (ne (const_int 0) (symbol_ref "TARGET_MIPS5900") )
+			(const_int 12)
+			(const_int 4))) ])
 
 (define_insn ""
   [(set (match_operand:DF 0 "register_operand" "=f")
@@ -2837,9 +2950,17 @@
   [(set (match_operand:SF 0 "register_operand" "=f")
 	(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
-  "sqrt.s\\t%0,%1"
+  "*
+  if (TARGET_MIPS5900)
+	  return (\"%(nop\;nop\;sqrt.s\\t%0,%1%)\");
+  return (\"sqrt.s\\t%0,%1\");
+  "
   [(set_attr "type"	"fsqrt")
-   (set_attr "mode"	"SF")])
+   (set_attr "mode"	"SF")
+   (set (attr "length") 
+   	(if_then_else (ne (const_int 0) (symbol_ref "TARGET_MIPS5900") )
+			(const_int 12)
+			(const_int 4))) ])
 
 (define_insn ""
   [(set (match_operand:DF 0 "register_operand" "=f")
@@ -2859,6 +2980,16 @@
   [(set_attr "type"	"fsqrt")
    (set_attr "mode"	"SF")])
 
+(define_insn ""
+  [(set (match_operand:SF 0 "register_operand" "=f")
+      (div:SF (match_operand:SF 1 "register_operand" "f")
+	      (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
+  "TARGET_MIPS5900 && TARGET_HARD_FLOAT && flag_fast_math"
+  "%(nop\;nop\;rsqrt.s\\t%0,%1,%2%)"
+  [(set_attr "type"	"frsqrt")
+   (set_attr "mode"	"SF")
+   (set_attr "length"	"3")])
+
 
 ;;
 ;;  ....................
@@ -2956,6 +3087,38 @@
   dslots_jump_filled += 2;
   operands[4] = const0_rtx;
 
+  if (TARGET_MIPS5900 && !TARGET_NO_LENGTHEN_LOOP ) {
+    if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
+      return \"%(\\
+move\\t%0,%z4\\n\\
+\\tbeq\\t%1,%z4,2f\\n\\
+1:\\tand\\t%2,%1,0x0001\\n\\
+\\taddu\\t%0,%0,1\\n\\
+\\tbne\\t%2,%z4,2f\\n\\
+\\tsrl\\t%1,%1,1\\n\\
+\\n\\
+\\tand\\t%2,%1,0x0001\\n\\
+\\taddu\\t%0,%0,1\\n\\
+\\tbeq\\t%2,%z4,1b\\n\\
+\\tsrl\\t%1,%1,1\\n\\
+2:%)\";
+
+    return \"%(\\
+move\\t%0,%z4\\n\\
+\\tmove\\t%3,%1\\n\\
+\\tbeq\\t%3,%z4,2f\\n\\
+1:\\tand\\t%2,%3,0x0001\\n\\
+\\taddu\\t%0,%0,1\\n\\
+\\tbne\\t%2,%z4,2f\\n\\
+\\tsrl\\t%3,%3,1\\n\\
+\\n\\
+\\tand\\t%2,%3,0x0001\\n\\
+\\taddu\\t%0,%0,1\\n\\
+\\tbeq\\t%2,%z4,1b\\n\\
+\\tsrl\\t%3,%3,1\\n\\
+2:%)\";
+  }
+
   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
     return \"%(\\
 move\\t%0,%z4\\n\\
@@ -2978,7 +3141,11 @@
 }"
   [(set_attr "type"	"multi")
    (set_attr "mode"	"SI")
-   (set_attr "length"	"12")])
+   (set (attr "length") 
+   	(if_then_else (and (ne (const_int 0) (symbol_ref "TARGET_MIPS5900") )
+   		(eq (const_int 0) (symbol_ref "TARGET_NO_LENGTHEN_LOOP")))
+	(const_int 44)
+	(const_int  24))) ])
 
 (define_insn "ffsdi2"
   [(set (match_operand:DI 0 "register_operand" "=&d")
@@ -2992,6 +3159,38 @@
   dslots_jump_filled += 2;
   operands[4] = const0_rtx;
 
+  if (TARGET_MIPS5900 && !TARGET_NO_LENGTHEN_LOOP ) {
+    if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
+      return \"%(\\
+move\\t%0,%z4\\n\\
+\\tbeq\\t%1,%z4,2f\\n\\
+1:\\tand\\t%2,%1,0x0001\\n\\
+\\tdaddu\\t%0,%0,1\\n\\
+\\tbne\\t%2,%z4,2f\\n\\
+\\tdsrl\\t%1,%1,1\\n\\
+\\n\\
+\\tand\\t%2,%1,0x0001\\n\\
+\\tdaddu\\t%0,%0,1\\n\\
+\\tbeq\\t%2,%z4,1b\\n\\
+\\tdsrl\\t%1,%1,1\\n\\
+2:%)\";
+
+    return \"%(\\
+move\\t%0,%z4\\n\\
+\\tmove\\t%3,%1\\n\\
+\\tbeq\\t%3,%z4,2f\\n\\
+1:\\tand\\t%2,%3,0x0001\\n\\
+\\tdaddu\\t%0,%0,1\\n\\
+\\tbne\\t%2,%z4,2f\\n\\
+\\tdsrl\\t%3,%3,1\\n\\
+\\n\\
+\\tand\\t%2,%3,0x0001\\n\\
+\\tdaddu\\t%0,%0,1\\n\\
+\\tbeq\\t%2,%z4,1b\\n\\
+\\tdsrl\\t%3,%3,1\\n\\
+2:%)\";
+  }
+
   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
     return \"%(\\
 move\\t%0,%z4\\n\\
@@ -3014,7 +3213,11 @@
 }"
   [(set_attr "type"	"multi")
    (set_attr "mode"	"DI")
-   (set_attr "length"	"24")])
+   (set (attr "length") 
+   	(if_then_else (and (ne (const_int 0) (symbol_ref "TARGET_MIPS5900") )
+   		(eq (const_int 0) (symbol_ref "TARGET_NO_LENGTHEN_LOOP")))
+	(const_int 44)
+	(const_int  24))) ])
 
 
 ;;
@@ -6478,7 +6681,7 @@
   [(set (match_operand:DI 0 "register_operand" "=&d")
 	(ashift:DI (match_operand:DI 1 "register_operand" "d")
 		   (match_operand:SI 2 "register_operand" "d")))
-   (clobber (match_operand:SI 3 "register_operand" "=d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
   "*
 {
@@ -6512,7 +6715,7 @@
   [(set (match_operand:DI 0 "register_operand" "=d")
 	(ashift:DI (match_operand:DI 1 "register_operand" "d")
 		   (match_operand:SI 2 "small_int" "IJK")))
-   (clobber (match_operand:SI 3 "register_operand" "=d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
    && (INTVAL (operands[2]) & 32) != 0"
   "*
@@ -6564,7 +6767,7 @@
   [(set (match_operand:DI 0 "register_operand" "=d")
 	(ashift:DI (match_operand:DI 1 "register_operand" "d")
 		   (match_operand:SI 2 "small_int" "IJK")))
-   (clobber (match_operand:SI 3 "register_operand" "=d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
    && (INTVAL (operands[2]) & 63) < 32
    && (INTVAL (operands[2]) & 63) != 0"
@@ -6836,7 +7039,7 @@
   [(set (match_operand:DI 0 "register_operand" "=&d")
 	(ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
 		     (match_operand:SI 2 "register_operand" "d")))
-   (clobber (match_operand:SI 3 "register_operand" "=d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
   "*
 {
@@ -6870,7 +7073,7 @@
   [(set (match_operand:DI 0 "register_operand" "=d")
 	(ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
 		     (match_operand:SI 2 "small_int" "IJK")))
-   (clobber (match_operand:SI 3 "register_operand" "=d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
   "*
 {
@@ -6918,7 +7121,7 @@
   [(set (match_operand:DI 0 "register_operand" "=d")
 	(ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
 		     (match_operand:SI 2 "small_int" "IJK")))
-   (clobber (match_operand:SI 3 "register_operand" "=d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
    && (INTVAL (operands[2]) & 63) < 32
    && (INTVAL (operands[2]) & 63) != 0"
@@ -7217,7 +7420,7 @@
   [(set (match_operand:DI 0 "register_operand" "=&d")
 	(lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
 		     (match_operand:SI 2 "register_operand" "d")))
-   (clobber (match_operand:SI 3 "register_operand" "=d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
   "*
 {
@@ -7251,7 +7454,7 @@
   [(set (match_operand:DI 0 "register_operand" "=d")
 	(lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
 		     (match_operand:SI 2 "small_int" "IJK")))
-   (clobber (match_operand:SI 3 "register_operand" "=d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
    && (INTVAL (operands[2]) & 32) != 0"
   "*
@@ -7303,7 +7506,7 @@
   [(set (match_operand:DI 0 "register_operand" "=d")
 	(lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
 		   (match_operand:SI 2 "small_int" "IJK")))
-   (clobber (match_operand:SI 3 "register_operand" "=d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
    && (INTVAL (operands[2]) & 63) < 32
    && (INTVAL (operands[2]) & 63) != 0"
@@ -9678,6 +9881,39 @@
   [(set_attr "type"	"call")
    (set_attr "mode"	"none")])
 
+;;
+;; use jalr instead of jal
+;;
+(define_insn "call_indirect_internal"
+  [ (unspec_volatile [ 
+  	(match_operand 0 "call_insn_operand" "ri")
+	(match_operand 1 "" "i")
+        (match_operand:SI 2 "register_operand" "=d") ] 30 )]
+  ""
+  "*
+{
+  register rtx target = operands[0];
+
+  if (GET_CODE (target) == SYMBOL_REF)
+    {
+      if (GET_MODE (target) == SImode)
+	return \"la\\t%^,%0\\n\\tjalr\\t%2,%^\";
+      else
+	return \"dla\\t%^,%0\\n\\tjalr\\t%2,%^\";
+    }
+  else if (GET_CODE (target) == CONST_INT)
+    return \"li\\t%^,%0\\n\\tjalr\\t%2,%^\";
+  else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
+    return \"move\\t%^,%0\\n\\tjalr\\t%2,%^\";
+  else
+    return \"jalr\\t%2,%0\";
+}"
+  [(set_attr "type"	"call")
+   (set_attr "mode"	"none")
+   (set_attr "length"	"8")])
+
+;;
+
 (define_insn "call_internal2"
   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
 	 (match_operand 1 "" "i"))
@@ -9691,6 +9927,8 @@
     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
   else if (CONSTANT_ADDRESS_P (target))
     {
+      if (REGNO (operands[2]) == (31 + GP_REG_FIRST))
+	return \"jal\\t%0\";
       if (GET_MODE (target) == SImode)
 	return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
       else
@@ -9899,6 +10137,8 @@
     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
   else if (CONSTANT_ADDRESS_P (target))
     {
+      if (REGNO (operands[3]) == (31 + GP_REG_FIRST))
+	return \"jal\\t%1\";
       if (GET_MODE (target) == SImode)
 	return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
       else
@@ -10034,6 +10274,8 @@
     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
   else if (CONSTANT_ADDRESS_P (target))
     {
+      if (REGNO (operands[4]) == (31 + GP_REG_FIRST))
+	return \"jal\\t%1\";
       if (GET_MODE (target) == SImode)
 	return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
       else
@@ -10091,6 +10333,14 @@
   [(set_attr "type"	"nop")
    (set_attr "mode"	"none")])
 
+(define_insn "nop_internal"
+  [ (unspec_volatile [(const_int 0)] 31)]
+  "TARGET_MIPS5900"
+  "%(nop%)"
+  [(set_attr "type"	"nop")
+   (set_attr "mode"	"none")
+   (set_attr "length"	"1")])
+
 ;; The MIPS chip does not seem to require stack probes.
 ;;
 ;; (define_expand "probe"
@@ -10164,7 +10414,7 @@
 			  (const_int 0)])
 	 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
 	 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
-  "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
+  "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && (!TARGET_MIPS5900 || TARGET_64BIT)"
   "@
     mov%B4\\t%0,%z2,%1
     mov%b4\\t%0,%z3,%1"
@@ -10179,7 +10429,7 @@
 			  (const_int 0)])
 	 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
 	 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
-  "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
+  "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && (!TARGET_MIPS5900 || TARGET_64BIT)"
   "@
     mov%B4\\t%0,%z2,%1
     mov%b4\\t%0,%z3,%1"
@@ -10305,6 +10555,10 @@
   "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
   "
 {
+  if (TARGET_MIPS5900
+      && GET_MODE_CLASS (GET_MODE (branch_cmp[0])) == MODE_FLOAT)
+    FAIL;
+
   gen_conditional_move (operands);
   DONE;
 }")
@@ -10315,9 +10569,10 @@
 	(if_then_else:DI (match_dup 5)
 			 (match_operand:DI 2 "se_reg_or_0_operand" "")
 			 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
-  "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
+  "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && (!TARGET_MIPS5900 || TARGET_64BIT)"
   "
 {
+
   gen_conditional_move (operands);
   DONE;
 }")
diff -urN gcc-3.0.4-eelinux.orig/gcc/config/mips/t-eelinux gcc-3.0.4-eelinux/gcc/config/mips/t-eelinux
--- gcc-3.0.4-eelinux.orig/gcc/config/mips/t-eelinux	Wed Dec 31 18:00:00 1969
+++ gcc-3.0.4-eelinux/gcc/config/mips/t-eelinux	Thu Mar  7 03:47:25 2002
@@ -0,0 +1,77 @@
+# Suppress building libgcc1.a, since the MIPS compiler port is complete
+# and does not need anything from libgcc1.a.
+## LIBGCC1 =
+## CROSS_LIBGCC1 =
+###### from t-r5900
+# Suppress building libgcc1.a, since the MIPS compiler port is complete
+# and does not need anything from libgcc1.a.
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+# We must build libgcc2.a with -G 0, in case the user wants to link
+# without the $gp register.
+TARGET_LIBGCC2_CFLAGS = -G 0
+
+# We want fine grained libraries.
+# fp-bit.c and dp-bit.c are really part of libgcc1, 
+# but this will cause them to be
+# built correctly, so... [taken from t-sparclite]
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+LIB2FUNCS_EXTRA = mips-bb-helper.asm ee-perfcounter.c 
+
+mips-bb-helper.asm:
+	rm -f mips-bb-helper.asm
+	ln -s $(srcdir)/config/mips/mips-bb-helper.asm mips-bb-helper.asm
+
+ee-perfcounter.c:
+	rm -f ee-perfcounter.c
+	ln -s $(srcdir)/config/mips/ee-perfcounter.c  ee-perfcounter.c
+
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+	echo '#ifdef __MIPSEL__' > dp-bit.c
+	echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
+	echo '#endif' >> dp-bit.c
+	echo '#define US_SOFTWARE_GOFAST' >> dp-bit.c
+	cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+	echo '#define FLOAT' > fp-bit.c
+	echo '#ifdef __MIPSEL__' >> fp-bit.c
+	echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
+	echo '#endif' >> fp-bit.c
+	echo '#define US_SOFTWARE_GOFAST' >> fp-bit.c
+	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+MULTILIB_OPTIONS = msoft-float
+MULTILIB_DIRNAMES = soft-float
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+#
+# TImode runtime support
+#
+LIBGCC_TIMODE_SRC = $(srcdir)/config/mips/libgcc2-timode.c
+TIMODE_FUNCS_LIST = \
+	ashlti3		\
+	ashrti3		\
+	cmpti2		\
+	divti3		\
+	ffsti2		\
+	fixdfti		\
+	fixunsdfti	\
+	floattidf	\
+	floattisf	\
+	lshrti3		\
+	modti3		\
+	multi3		\
+	negti2		\
+	ucmpti2		\
+	udivti3		\
+	umodti3
+
+
+LIB2FUNCS_TI = $(TIMODE_FUNCS_LIST)
+
diff -urN gcc-3.0.4-eelinux.orig/gcc/config/mips/t-linux gcc-3.0.4-eelinux/gcc/config/mips/t-linux
--- gcc-3.0.4-eelinux.orig/gcc/config/mips/t-linux	Wed Dec 31 18:00:00 1969
+++ gcc-3.0.4-eelinux/gcc/config/mips/t-linux	Thu Mar  7 03:47:25 2002
@@ -0,0 +1,15 @@
+# Suppress building libgcc1.a, since the MIPS compiler port is complete
+# and does not need anything from libgcc1.a.
+## LIBGCC1 =
+## CROSS_LIBGCC1 =
+
+# We must build libgcc2.a with -G 0, in case the user wants to link
+# without the $gp register.
+TARGET_LIBGCC2_CFLAGS = -G 0
+
+LIB2FUNCS_EXTRA = mips-bb-helper.asm 
+
+mips-bb-helper.asm:
+	rm -f mips-bb-helper.asm
+	ln -s $(srcdir)/config/mips/mips-bb-helper.asm mips-bb-helper.asm
+
diff -urN gcc-3.0.4-eelinux.orig/gcc/config.gcc gcc-3.0.4-eelinux/gcc/config.gcc
--- gcc-3.0.4-eelinux.orig/gcc/config.gcc	Fri Feb 15 08:42:53 2002
+++ gcc-3.0.4-eelinux/gcc/config.gcc	Thu Mar  7 03:47:25 2002
@@ -2398,6 +2398,18 @@
 	# On NetBSD, the headers are already okay, except for math.h.
 	tmake_file=t-netbsd
 	;;
+mipsEE*-*-linux*)		# MIPS EE w/ Linux & ELF
+	xmake_file=x-linux
+	xm_file="xm-siglist.h ${xm_file}"
+	tmake_file="mips/t-eelinux"
+        case $machine in
+                mipsEEel-*)  tm_file="mips/elfl.h mips/eelinux.h" ;;
+                *)         tm_file="mips/elf.h mips/eelinux.h" ;;
+        esac
+	extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+	gnu_ld=yes
+	gas=yes
+	;;
 mips*-*-linux*)				# Linux MIPS, either endian.
 	xmake_file=x-linux
 	case $machine in
@@ -2617,6 +2629,24 @@
 	then
 		use_collect2=yes
 	fi
+	;;
+mips*el-*-linux*)		# Little endian MIPS w/ Linux & ELF
+	tm_file="mips/elfl.h mips/linux.h"
+	tmake_file="mips/t-linux"
+	xm_file="mips/xm-mips.h xm-linux.h"
+         xmake_file=none
+	gnu_ld=yes gas=yes
+	extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+         fixincludes=Makefile.in
+	;;
+mips*-*-linux*)			# Big endian MIPS w/ Linux & ELF
+	tm_file="mips/elf.h mips/linux.h"
+	tmake_file="mips/t-linux"
+	xm_file="mips/xm-mips.h xm-linux.h"
+         xmake_file=none
+	gnu_ld=yes gas=yes
+	extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+         fixincludes=Makefile.in
 	;;
 mips-*-gnu*)
 	;;
diff -urN gcc-3.0.4-eelinux.orig/gcc/ifcvt.c gcc-3.0.4-eelinux/gcc/ifcvt.c
--- gcc-3.0.4-eelinux.orig/gcc/ifcvt.c	Thu Nov 29 17:29:35 2001
+++ gcc-3.0.4-eelinux/gcc/ifcvt.c	Thu Mar  7 03:47:25 2002
@@ -1016,10 +1016,11 @@
       if (reversep)
 	{
 	  code = reverse_condition (code);
-	  tmp = a, a = b, b = tmp;
-	  tmp = insn_a, insn_a = insn_b, insn_b = tmp;
+	  tmp = a; a = b; b = tmp;
+	  tmp = insn_a; insn_a = insn_b; insn_b = tmp;
 	}
     }
+
 
   start_sequence ();
 
diff -urN gcc-3.0.4-eelinux.orig/gcc/libgcc2-timode.c gcc-3.0.4-eelinux/gcc/libgcc2-timode.c
--- gcc-3.0.4-eelinux.orig/gcc/libgcc2-timode.c	Wed Dec 31 18:00:00 1969
+++ gcc-3.0.4-eelinux/gcc/libgcc2-timode.c	Thu Mar  7 03:47:25 2002
@@ -0,0 +1,792 @@
+/* GCC rutime support routines for TI mode */
+
+/* Copyright (C) 2001  Sony Computer Entertainment Inc. 
+   Copyright 2001  Sony Corportaion.  */
+
+/* This file is derived from libgcc2.c and subject to the original 
+   license of libgcc2.c, as follows. */
+
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 92-98, 1999 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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+
+#include "tconfig.h"
+
+/* We disable this when inhibit_libc, so that gcc can still be built without
+   needing header files first.  */
+/* ??? This is not a good solution, since prototypes may be required in
+   some cases for correct code.  See also frame.c.  */
+
+#include "machmode.h"
+#include "defaults.h"
+
+#ifndef LIBGCC2_WORDS_BIG_ENDIAN
+#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
+#endif
+
+
+/* In this file, we are interfacing to calls generated by the compiler 
+   itself.  These calls pass values into these routines which have very 
+   specific modes (rather than very specific types), and these 
+   compiler-generated calls also expect any return values to have very 
+   specific modes (rather than very specific types).  Thus, we need to 
+   avoid using regular C language type names in this part of the file
+   because the sizes for those types can be configured to be anything.
+   Instead we use the following special type names.  */
+
+typedef unsigned int UTItype __attribute__((mode(TI)));
+typedef          int  TItype __attribute__((mode(TI)));
+typedef unsigned int UDItype __attribute__((mode(DI)));
+typedef          int  DItype __attribute__((mode(DI)));
+typedef unsigned int UQItype __attribute__((mode(QI)));
+typedef          int  QItype __attribute__((mode(QI)));
+
+typedef		float SFtype	__attribute__ ((mode (SF)));
+typedef		float DFtype	__attribute__ ((mode (DF)));
+
+typedef int word_type __attribute__ ((mode (__word__)));
+
+/* Make sure that we don't accidentally use any normal C language 
+   built-in type names in the first part of this file.  Instead we want 
+   to use *only* the type names defined above.  
+   The following macro definitions insure that if we *do* accidentally 
+   use some normal C language built-in type name, we will get a syntax 
+   error.  */
+
+#define char bogus_type
+#define short bogus_type
+#define int bogus_type
+#define long bogus_type
+#define unsigned bogus_type
+#define float bogus_type
+#define double bogus_type
+
+
+#ifndef BITS_PER_UNIT
+#define BITS_PER_UNIT 8
+#endif
+#ifndef DI_TYPE_SIZE
+#define DI_TYPE_SIZE 64
+#endif
+
+
+/* TIstructs are pairs of DItype values in the order determined by
+   LIBGCC2_WORDS_BIG_ENDIAN.  */
+
+#if LIBGCC2_WORDS_BIG_ENDIAN
+struct TIstruct {DItype high, low;};
+#else
+struct TIstruct {DItype low, high;};
+#endif
+
+/* We need this union to unpack/pack TImode values, since we don't have
+   any arithmetic yet.  Incoming TImode parameters are stored into the
+   `ti' field, and the unpacked result is read from the struct `d'.  */
+
+typedef union
+{
+  struct TIstruct d;
+  TItype ti;
+} TIunion;
+
+/*  for  
+	__fixunsdfti
+	 __floattidf
+ */ 
+#define DI_WORD_SIZE (sizeof (DItype) * BITS_PER_UNIT)
+#define HIGH_DI_WORD_COEFF (((UTItype) 1) << DI_WORD_SIZE)
+#define HIGH_DI_HALFWORD_COEFF (((UDItype) 1) << (DI_WORD_SIZE / 2))
+
+
+
+#if (defined (L_udivti3) || defined (L_divti3) || defined (L_multi3) ||\
+     defined (L_umodti3) || defined (L_modti3))
+/* ----------------------------------------------------------------- */
+/* BEGIN: derived from longlog.h */
+/* for  
+	__udivmoddi4
+	__multi3
+	__dviti3
+	__udviti3
+	__modti3
+	__umodti3
+*/
+
+#define __ti_B (((UDItype)1) << (DI_TYPE_SIZE / 2))
+#define __ti_lowpart(t) ((UDItype) (t) % __ti_B)
+#define __ti_highpart(t) ((UDItype) (t) / __ti_B)
+
+#define umul_ppmm_di(w1, w0, u, v) 					\
+do {									\
+    UDItype __x0, __x1, __x2, __x3;					\
+    UDItype __ul, __vl, __uh, __vh;					\
+									\
+    __ul = __ti_lowpart (u);						\
+    __uh = __ti_highpart (u);						\
+    __vl = __ti_lowpart (v);						\
+    __vh = __ti_highpart (v);						\
+									\
+    __x0 = (UDItype) __ul * __vl;					\
+    __x1 = (UDItype) __ul * __vh;					\
+    __x2 = (UDItype) __uh * __vl;					\
+    __x3 = (UDItype) __uh * __vh;					\
+									\
+    __x1 += __ti_highpart (__x0);/* this can't give carry */		\
+    __x1 += __x2;               /* but this indeed can */		\
+    if (__x1 < __x2)            /* did we get it? */			\
+      __x3 += __ti_B;           /* yes, add it in the proper pos. */	\
+									\
+    (w1) = __x3 + __ti_highpart (__x1);					\
+    (w0) = __ti_lowpart (__x1) * __ti_B + __ti_lowpart (__x0);		\
+} while (0)
+
+#define __umulditi3(u, v) \
+  ({TIunion __w;                                                        \
+    umul_ppmm_di (__w.d.high, __w.d.low, u, v);                            \
+    __w.ti; })
+
+
+
+/* Define this unconditionally, so it can be used for debugging.  */
+#define udiv_qrnnd_c_di(q, r, n1, n0, d) \
+  do {                                                                  \
+    UDItype __d1, __d0, __q1, __q0;                                     \
+    UDItype __r1, __r0, __m;                                            \
+    __d1 = __ti_highpart (d);                                           \
+    __d0 = __ti_lowpart (d);                                            \
+                                                                        \
+    __r1 = (n1) % __d1;                                                 \
+    __q1 = (n1) / __d1;                                                 \
+    __m = (UDItype) __q1 * __d0;                                        \
+    __r1 = __r1 * __ti_B | __ti_highpart (n0);                          \
+    if (__r1 < __m)                                                     \
+      {                                                                 \
+        __q1--, __r1 += (d);                                            \
+        if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+          if (__r1 < __m)                                               \
+            __q1--, __r1 += (d);                                        \
+      }                                                                 \
+    __r1 -= __m;                                                        \
+                                                                        \
+    __r0 = __r1 % __d1;                                                 \
+    __q0 = __r1 / __d1;                                                 \
+    __m = (UDItype) __q0 * __d0;                                        \
+    __r0 = __r0 * __ti_B | __ti_lowpart (n0);                           \
+    if (__r0 < __m)                                                     \
+      {                                                                 \
+        __q0--, __r0 += (d);                                            \
+        if (__r0 >= (d))                                                \
+          if (__r0 < __m)                                               \
+            __q0--, __r0 += (d);                                        \
+      }                                                                 \
+    __r0 -= __m;                                                        \
+                                                                        \
+    (q) = (UDItype) __q1 * __ti_B | __q0;                               \
+    (r) = __r0;                                                         \
+  } while (0)
+
+
+#define sub_ddmmss_di(sh, sl, ah, al, bh, bl) \
+  do {                                                                  \
+    UDItype __x;                                                        \
+    __x = (al) - (bl);                                                  \
+    (sh) = (ah) - (bh) - (__x > (al));                                  \
+    (sl) = __x;                                                         \
+  } while (0)
+
+#define count_leading_zeros_di(count, x) \
+  do {                                                                  \
+    UDItype __xr = (x);                                                 \
+    UDItype __a;                                                        \
+                                                                        \
+      {                                                                 \
+        for (__a = DI_TYPE_SIZE - 8; __a > 0; __a -= 8)                 \
+          if (((__xr >> __a) & 0xff) != 0)                              \
+            break;                                                      \
+      }                                                                 \
+                                                                        \
+    (count) = DI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);            \
+  } while (0)
+
+
+
+/* END: derived from longlog.h */
+/* ----------------------------------------------------------------- */
+#endif /* (defined (L_udivti3) || defined (L_divti3) || defined (L_multi3) ||
+           defined (L_umodti3) || defined (L_modti3)) */
+
+
+#if defined (L_negti2) || defined (L_divti3) || defined (L_modti3)
+#if defined (L_divti3) || defined (L_modti3)
+static inline
+#endif
+TItype
+__negti2 (TItype u)
+{
+  TIunion w;
+  TIunion uu;
+
+  uu.ti = u;
+
+  w.d.low = -uu.d.low;
+  w.d.high = -uu.d.high - ((UDItype) w.d.low > 0);
+
+  return w.ti;
+}
+#endif
+
+/* Unless shift functions are defined whith full ANSI prototypes,
+   parameter b will be promoted to int if word_type is smaller than an int.  */
+#ifdef L_lshrti3
+TItype
+__lshrti3 (TItype u, word_type b)
+{
+  TIunion w;
+  word_type bm;
+  TIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ti = u;
+
+  bm = (sizeof (DItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.d.high = 0;
+      w.d.low = (UDItype)uu.d.high >> -bm;
+    }
+  else
+    {
+      UDItype carries = (UDItype)uu.d.high << bm;
+      w.d.high = (UDItype)uu.d.high >> b;
+      w.d.low = ((UDItype)uu.d.low >> b) | carries;
+    }
+
+  return w.ti;
+}
+#endif
+
+#ifdef L_ashlti3
+TItype
+__ashlti3 (TItype u, word_type b)
+{
+  TIunion w;
+  word_type bm;
+  TIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ti = u;
+
+  bm = (sizeof (DItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.d.low = 0;
+      w.d.high = (UDItype)uu.d.low << -bm;
+    }
+  else
+    {
+      UDItype carries = (UDItype)uu.d.low >> bm;
+      w.d.low = (UDItype)uu.d.low << b;
+      w.d.high = ((UDItype)uu.d.high << b) | carries;
+    }
+
+  return w.ti;
+}
+#endif
+
+#ifdef L_ashrti3
+TItype
+__ashrti3 (TItype u, word_type b)
+{
+  TIunion w;
+  word_type bm;
+  TIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ti = u;
+
+  bm = (sizeof (DItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      /* w.d.high = 1..1 or 0..0 */
+      w.d.high = uu.d.high >> (sizeof (DItype) * BITS_PER_UNIT - 1);
+      w.d.low = uu.d.high >> -bm;
+    }
+  else
+    {
+      UDItype carries = (UDItype)uu.d.high << bm;
+      w.d.high = uu.d.high >> b;
+      w.d.low = ((UDItype)uu.d.low >> b) | carries;
+    }
+
+  return w.ti;
+}
+#endif
+
+#ifdef L_ffsti2
+TItype
+__ffsti2 (TItype u)
+{
+  TIunion uu, w;
+  uu.ti = u;
+  w.d.high = 0;
+  w.d.low = __ffsdi2 (uu.d.low);
+  if (w.d.low != 0)
+    return w.ti;
+  w.d.low = __ffsdi2 (uu.d.high);
+  if (w.d.low != 0)
+    {
+      w.d.low += BITS_PER_UNIT * sizeof (DItype);
+      return w.ti;
+    }
+  return w.ti;
+}
+#endif
+
+
+#ifdef L_multi3
+TItype
+__multi3 (TItype u, TItype v)
+{
+  TIunion w;
+  TIunion uu, vv;
+
+  uu.ti = u,
+  vv.ti= v;
+
+  w.ti = __umulditi3 (uu.d.low, vv.d.low);
+  w.d.high += ((UDItype) uu.d.low * (UDItype) vv.d.high
+	       + (UDItype) uu.d.high * (UDItype) vv.d.low);
+
+  return w.ti;
+}
+#endif
+
+#if (defined (L_udivti3) || defined (L_divti3) || \
+     defined (L_umodti3) || defined (L_modti3))
+#define L_udivmodti4
+#endif
+
+#ifdef L_udivmodti4
+static 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,
+};
+
+#if (defined (L_udivti3) || defined (L_divti3) || \
+     defined (L_umodti3) || defined (L_modti3))
+static inline
+#endif
+UTItype
+__udivmodti4 (UTItype n, UTItype d, UTItype *rp)
+{
+  TIunion ww;
+  TIunion nn, dd;
+  TIunion rr;
+  UDItype d0, d1, n0, n1, n2;
+  UDItype q0, q1;
+  UDItype b, bm;
+
+  nn.ti = n;
+  dd.ti = d;
+
+  d0 = dd.d.low;
+  d1 = dd.d.high;
+  n0 = nn.d.low;
+  n1 = nn.d.high;
+
+
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  count_leading_zeros_di (bm, d0);
+
+	  if (bm != 0)
+	    {
+	      /* Normalize, i.e. make the most significant bit of the
+		 denominator set.  */
+
+	      d0 = d0 << bm;
+	      n1 = (n1 << bm) | (n0 >> (DI_TYPE_SIZE - bm));
+	      n0 = n0 << bm;
+	    }
+
+	  udiv_qrnnd_c_di (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0 >> bm.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  count_leading_zeros_di (bm, d0);
+
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 leading quotient digit q1 = 1).
+
+		 This special case is necessary, not an optimization.
+		 (Shifts counts of DI_TYPE_SIZE are undefined.)  */
+
+	      n1 -= d0;
+	      q1 = 1;
+	    }
+	  else
+	    {
+	      /* Normalize.  */
+
+	      b = DI_TYPE_SIZE - bm;
+
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd_c_di (q1, n1, n2, n1, d0);
+	    }
+
+	  /* n1 != d0...  */
+
+	  udiv_qrnnd_c_di (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0 >> bm.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.d.low = n0 >> bm;
+	  rr.d.high = 0;
+	  *rp = rr.ti;
+	}
+    }
+  else
+    {
+      if (d1 > n1)
+	{
+	  /* 00 = nn / DD */
+
+	  q0 = 0;
+	  q1 = 0;
+
+	  /* Remainder in n1n0.  */
+	  if (rp != 0)
+	    {
+	      rr.d.low = n0;
+	      rr.d.high = n1;
+	      *rp = rr.ti;
+	    }
+	}
+      else
+	{
+	  /* 0q = NN / dd */
+
+	  count_leading_zeros_di (bm, d1);
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 quotient digit q0 = 0 or 1).
+
+		 This special case is necessary, not an optimization.  */
+
+	      /* The condition on the next line takes advantage of that
+		 n1 >= d1 (true due to program flow).  */
+	      if (n1 > d1 || n0 >= d0)
+		{
+		  q0 = 1;
+		  sub_ddmmss_di (n1, n0, n1, n0, d1, d0);
+		}
+	      else
+		q0 = 0;
+
+	      q1 = 0;
+
+	      if (rp != 0)
+		{
+		  rr.d.low = n0;
+		  rr.d.high = n1;
+		  *rp = rr.ti;
+		}
+	    }
+	  else
+	    {
+	      UDItype m1, m0;
+	      /* Normalize.  */
+
+	      b = DI_TYPE_SIZE - bm;
+
+	      d1 = (d1 << bm) | (d0 >> b);
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd_c_di (q0, n1, n2, n1, d1);
+	      umul_ppmm_di (m1, m0, q0, d0);
+
+	      if (m1 > n1 || (m1 == n1 && m0 > n0))
+		{
+		  q0--;
+		  sub_ddmmss_di (m1, m0, m1, m0, d1, d0);
+		}
+
+	      q1 = 0;
+
+	      /* Remainder in (n1n0 - m1m0) >> bm.  */
+	      if (rp != 0)
+		{
+		  sub_ddmmss_di (n1, n0, n1, n0, m1, m0);
+		  rr.d.low = (n1 << b) | (n0 >> bm);
+		  rr.d.high = n1 >> bm;
+		  *rp = rr.ti;
+		}
+	    }
+	}
+    }
+
+  ww.d.low = q0;
+  ww.d.high = q1;
+  return ww.ti;
+}
+#endif
+
+#ifdef L_divti3
+UTItype __udivmodti4 ();
+
+TItype
+__divti3 (TItype u, TItype v)
+{
+  word_type c = 0;
+  TIunion uu, vv;
+  TItype w;
+
+  uu.ti = u;
+  vv.ti = v;
+
+  if (uu.d.high < 0)
+    c = ~c,
+    uu.ti = __negti2 (uu.ti);
+  if (vv.d.high < 0)
+    c = ~c,
+    vv.ti = __negti2 (vv.ti);
+
+  w = __udivmodti4 (uu.ti, vv.ti, (UTItype *) 0);
+  if (c)
+    w = __negti2 (w);
+
+  return w;
+}
+#endif
+
+#ifdef L_modti3
+UTItype __udivmodti4 ();
+
+TItype
+__modti3 (TItype u, TItype v)
+{
+  word_type c = 0;
+  TIunion uu, vv;
+  TItype w;
+
+  uu.ti = u;
+  vv.ti = v;
+
+  if (uu.d.high < 0)
+    c = ~c,
+    uu.ti = __negti2 (uu.ti);
+  if (vv.d.high < 0)
+    vv.ti = __negti2 (vv.ti);
+
+  (void) __udivmodti4 (uu.ti, vv.ti, (UTItype *)&w);
+  if (c)
+    w = __negti2 (w);
+
+  return w;
+}
+#endif
+
+#ifdef L_umodti3
+UTItype __udivmodti4 ();
+
+UTItype
+__umodti3 (UTItype u, UTItype v)
+{
+  UTItype w;
+
+  (void) __udivmodti4 (u, v, &w);
+
+  return w;
+}
+#endif
+
+
+#ifdef L_udivti3
+UTItype __udivmodti4 ();
+UTItype
+__udivti3 (UTItype n, UTItype d)
+{
+  return __udivmodti4 (n, d, (UTItype *) 0);
+}
+#endif
+
+#ifdef L_cmpti2
+word_type
+__cmpti2 (TItype a, TItype b)
+{
+  TIunion au, bu;
+
+  au.ti = a, bu.ti = b;
+
+  if (au.d.high < bu.d.high)
+    return 0;
+  else if (au.d.high > bu.d.high)
+    return 2;
+  if ((UDItype) au.d.low < (UDItype) bu.d.low)
+    return 0;
+  else if ((UDItype) au.d.low > (UDItype) bu.d.low)
+    return 2;
+  return 1;
+}
+#endif
+
+#ifdef L_ucmpti2
+word_type
+__ucmpti2 (UTItype a, UTItype b)
+{
+  TIunion au, bu;
+
+  au.ti = a, bu.ti = b;
+
+  if ((UDItype) au.d.high < (UDItype) bu.d.high)
+    return 0;
+  else if ((UDItype) au.d.high > (UDItype) bu.d.high)
+    return 2;
+  if ((UDItype) au.d.low < (UDItype) bu.d.low)
+    return 0;
+  else if ((UDItype) au.d.low > (UDItype) bu.d.low)
+    return 2;
+  return 1;
+}
+#endif
+
+
+/*
+  Followings are not neeeded, because TF or XF mode is not supported. 
+   __fixunstfti(), __fixtfdi()
+   __fixunsxfti(), __fixxfti()
+*/
+
+#ifdef L_fixunsdfti
+TItype
+__fixunsdfti (DFtype a)
+{
+  DFtype b;
+  UTItype v;
+
+  if (a < 0)
+    return 0;
+
+  /* Compute high word of result, as a flonum.  */
+  b = (a / HIGH_DI_WORD_COEFF);
+  /* Convert that to fixed (but not to DItype!),
+     and shift it into the high word.  */
+  v = (UDItype) b;
+  v <<= DI_WORD_SIZE;
+  /* Remove high part from the DFtype, leaving the low part as flonum.  */
+  a -= (DFtype)v;
+  /* Convert that to fixed (but not to DItype!) and add it in.
+     Sometimes A comes out negative.  This is significant, since
+     A has more bits than a long int does.  */
+  if (a < 0)
+    v -= (UDItype) (- a);
+  else
+    v += (UDItype) a;
+  return v;
+}
+#endif
+
+#ifdef L_fixdfti
+TItype
+__fixdfti (DFtype a)
+{
+  if (a < 0)
+    return - __fixunsdfti (-a);
+  return __fixunsdfti (a);
+}
+#endif
+
+/*
+  Followings are not neeeded, because TF or XF mode is not supported. 
+	__floattixf
+	__floattitf
+*/
+
+#ifdef L_floattidf
+DFtype
+__floattidf (TItype u)
+{
+  DFtype d;
+
+  d = (DItype) (u >> DI_WORD_SIZE);
+  d *= HIGH_DI_HALFWORD_COEFF;
+  d *= HIGH_DI_HALFWORD_COEFF;
+  d += (UDItype) (u & (HIGH_DI_WORD_COEFF - 1));
+
+  return d;
+}
+#endif
+
+#ifdef L_floattisf
+SFtype
+__floattisf (TItype u)
+{
+  DFtype df;
+  df = __floattidf (u);
+  return (SFtype) df;
+}
+#endif
diff -urN gcc-3.0.4-eelinux.orig/gcc/mklibgcc.in gcc-3.0.4-eelinux/gcc/mklibgcc.in
--- gcc-3.0.4-eelinux.orig/gcc/mklibgcc.in	Sun Nov 18 18:46:43 2001
+++ gcc-3.0.4-eelinux/gcc/mklibgcc.in	Thu Mar  7 03:47:25 2002
@@ -197,6 +197,21 @@
   libgcc2_st_objs="$libgcc2_st_objs ${name}${objext}"
 done
 
+if [ "$LIB2FUNCS_TI" ]; then
+  for name in $LIB2FUNCS_TI; do
+    for ml in $MULTILIBS; do
+      dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
+      flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
+      out="libgcc/${dir}/${name}${objext}"
+  
+      echo $out: $libgcc2_c_dep
+      echo "	$gcc_compile" '$(MAYBE_USE_COLLECT2)' $flags -DL$name \
+        -c '$(srcdir)/libgcc2-timode.c' -o $out
+    done
+    libgcc2_objs="$libgcc2_objs ${name}${objext}"
+  done
+fi
+
 if [ "$FPBIT" ]; then
   for name in $FPBIT_FUNCS; do
     for ml in $MULTILIBS; do
diff -urN gcc-3.0.4-eelinux.orig/gcc/toplev.c gcc-3.0.4-eelinux/gcc/toplev.c
--- gcc-3.0.4-eelinux.orig/gcc/toplev.c	Sun Oct 28 14:11:11 2001
+++ gcc-3.0.4-eelinux/gcc/toplev.c	Thu Mar  7 03:47:25 2002
@@ -3686,6 +3686,11 @@
   convert_to_eh_region_ranges ();
 #endif
 
+#ifdef MACHINE_DEPENDENT_REORG_FINAL
+   MACHINE_DEPENDENT_REORG_FINAL (insns);
+#endif
+
+
   /* Shorten branches.
 
      Note this must run before reg-stack because of death note (ab)use
diff -urN gcc-3.0.4-eelinux.orig/gcc/tree.c gcc-3.0.4-eelinux/gcc/tree.c
--- gcc-3.0.4-eelinux.orig/gcc/tree.c	Mon May 21 22:01:49 2001
+++ gcc-3.0.4-eelinux/gcc/tree.c	Thu Mar  7 03:47:25 2002
@@ -4817,17 +4817,13 @@
   intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode));
   intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode));
   intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
-#if HOST_BITS_PER_WIDE_INT >= 64
   intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
-#endif
 
   unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
   unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
   unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode));
   unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
-#if HOST_BITS_PER_WIDE_INT >= 64
   unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
-#endif
 }
 
 /* Call this function after calling build_common_tree_nodes and set_sizetype.
