A Linux/ARM patch for egcs 1.1.2

H.J. Lu hjl@lucon.org
Thu Feb 25 15:01:00 GMT 1999


Hi,

This patch will support Linux/ARM in egcs 1.1.2. If it is accepted,
I will work on the Linux/MIPS patch for egcs 1.1.2.

-- 
H.J. Lu (hjl@gnu.org)
---
1999-01-13  Philip Blundell  <pb@nexus.co.uk>

	* config.table (frags): Add support for ARM PIC.

--- clean/egcs-1.1.1/libiberty/config.table	Fri Dec  4 11:33:20 1998
+++ egcs-1.1.1/libiberty/config.table	Wed Jan 13 12:48:17 1999
@@ -19,6 +19,7 @@
 if [ "${shared}" = "yes" ]; then
   case "${host}" in
     *-*-cygwin32*) ;;
+    arm*-*) frags="${frags} ../../config/mh-armpic" ;;
     hppa*-*-*)	   frags="${frags} ../../config/mh-papic" ;;
     i[3456]86-*-*) frags="${frags} ../../config/mh-x86pic" ;;
     alpha*-*-linux*) frags="${frags} ../../config/mh-elfalphapic" ;;

1999-01-10  Philip Blundell  <philb@gnu.org>

	* configure.in (frags): Add support for ARM PIC.

diff -u --recursive --new-file clean/egcs-1.1.1/libio/configure.in egcs-1.1.1/libio/configure.in
--- clean/egcs-1.1.1/libio/configure.in	Fri Dec  4 11:33:21 1998
+++ egcs-1.1.1/libio/configure.in	Tue Jan 12 12:47:16 1999
@@ -55,6 +55,7 @@
   case "${target}" in
     hppa*-*)	 frags="${frags} ../../config/mh-papic" ;;
     i[3456]86-*) frags="${frags} ../../config/mh-x86pic" ;;
+    arm*-*) frags="${frags} ../../config/mh-armpic" ;;
     alpha*-*-linux*) frags="${frags} ../../config/mh-elfalphapic" ;;
 
     # There doesn't seem to be a simpler way to say all-ppc except AIX

1999-01-12  Philip Blundell  <philb@gnu.org>

	* configure.in (frags): Add support for ARM PIC.

diff -u --recursive --new-file clean/egcs-1.1.1/libstdc++/configure.in egcs-1.1.1/libstdc++/configure.in
--- clean/egcs-1.1.1/libstdc++/configure.in	Fri Dec  4 11:33:21 1998
+++ egcs-1.1.1/libstdc++/configure.in	Wed Jan 13 10:07:40 1999
@@ -39,6 +39,7 @@
 
 if [ "${shared}" = "yes" ]; then
   case "${target}" in
+    arm*-*) frags="${frags} ../../config/mh-armpic" ;;
     hppa*-*-*)		frags=../../config/mh-papic ;;
     i[3456]86-*-*)	frags=../../config/mh-x86pic ;;
     alpha*-*-linux*)	frags=../../config/mh-elfalphapic ;;

1999-01-07  Philip Blundell  <philb@gnu.org>

	* mh-armpic: New file.  Patch from Jim Pick <jim@jimpick.com>.
	* mt-armpic: Likewise.

diff -u --recursive --new-file clean/egcs-1.1.1/config/mh-armpic egcs-1.1.1/config/mh-armpic
--- clean/egcs-1.1.1/config/mh-armpic	Thu Jan  1 01:00:00 1970
+++ egcs-1.1.1/config/mh-armpic	Tue Jan 12 12:47:14 1999
@@ -0,0 +1 @@
+PICFLAG=-fPIC
diff -u --recursive --new-file clean/egcs-1.1.1/config/mt-armpic egcs-1.1.1/config/mt-armpic
--- clean/egcs-1.1.1/config/mt-armpic	Thu Jan  1 01:00:00 1970
+++ egcs-1.1.1/config/mt-armpic	Tue Jan 12 12:47:14 1999
@@ -0,0 +1 @@
+PICFLAG_FOR_TARGET=-fPIC

1999-01-07  Philip Blundell  <philb@gnu.org>

	* configure.in: Set target_makefile_frag and host_makefile_frag
	appropriately for ARM systems.  Patch from Jim Pick
	<jim@jimpick.com>

1998-12-20  Philip Blundell  <philb@gnu.org>

	* config.sub: Be more liberal when matching CPU names; allow
	`arm*' rather than just `arm'.

diff -u --recursive --new-file clean/egcs-1.1.1/config.sub egcs-1.1.1/config.sub
--- clean/egcs-1.1.1/config.sub	Fri Apr  3 17:21:57 1998
+++ egcs-1.1.1/config.sub	Tue Jan 12 12:47:14 1999
@@ -159,7 +159,7 @@
 case $basic_machine in
 	# Recognize the basic CPU types without company name.
 	# Some are omitted here because they have special meanings below.
-	tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+	tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm* \
 		| arme[lb] | pyramid | mn10200 | mn10300 \
 		| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
 		| alpha | alphaev5 | alphaev56 | alphapca56 | alphaev6 \
@@ -204,7 +204,7 @@
 		;;
 	# Recognize the basic CPU types with company name.
 	vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \
-	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm*-* | c[123]* \
 	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
 	      | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
 	      | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \


Tue Jan 12 19:52:19 1999  Richard Earnshaw (rearnsha@arm.com)

	* reload1.c (choose_reload_regs):  Don't inherit a reload if an input
	is tied to an earlyclobber operand.

1999-01-11  Philip Blundell  <philb@gnu.org>

	* config/arm/elf.h (ASM_OUTPUT_ALIGN): Leave argument as a power
	of 2 for the assembler.

1999-01-10  Philip Blundell  <philb@gnu.org>

	* config/arm/linux-elf.h (LIBGCC_SPEC): Include -lfloat if
	-msoft-float is given.
	(LIB_SPEC): Replace definition with one similar to that in
	config/linux.h.
	(HANDLE_SYSV_PRAGMA): Define.

	* config/arm/arm.h (CPP_FLOAT_SPEC): Define __APCS_FLOAT__ if
	-mapcs-float is given.

1999-01-06  Philip Blundell  <philb@gnu.org>

	* config/arm/linux-elf.h (DEFAULT_VTABLE_THUNKS): Always define to 
	1.  Patch from Jim Pick <jim@jimpick.com>.

1999-01-05  Philip Blundell  <philb@gnu.org>

	* config/arm/arm.md (consttable_12): New insn.
	* config/arm/arm.c (dump_table): Call it.
	
	* config/arm/linux-gas.h (INITIALIZE_TRAMPOLINE): Replace the
	default definition with one that clears the cache for StrongARM
	compatibility.

1999-01-04  Philip Blundell  <philb@gnu.org>

	* config/arm/linux-elf.h: On a 32-bit target, default to FP_SOFT3.
	(ASM_SPEC): When -mapcs-float is given, pass -mfloat to the
 	assembler so that it can fill in the ELF header correctly.

	* config/arm/arm.h (FUNCTION_ARG, etc): Rewrite more cleanly and
	fix a couple of bugs.
	* config/arm/arm.c: Likewise.

1998-12-27  Philip Blundell  <philb@gnu.org>

	* flow.c (find_basic_blocks_1): If RTX_FRAME_RELATED_P is set on a 
	label, don't add it to label_value_list.
	* rtl.h: Add comment documenting this behaviour.
	* config/arm/arm.c (arm_finalize_pic): Set RTX_FRAME_RELATED_P on
	the temporary label we generate.

1998-12-20  Philip Blundell  <philb@gnu.org>

	* config/arm/linux-elf26.h: Define SUBTARGET_EXTRA_LINK_SPEC
 	rather than SUBTARGET_LINK_SPEC directly.

	* config/arm/arm.h: Better support for apcs-float argument passing
	convention.
	* config/arm/arm.c: Likewise.

	* config/arm/linux-gas.h: Enable use of sys_cacheflush now that
	the latest kernels support it.

1998-11-26  Philip Blundell  <pb@nexus.co.uk>

	* config/arm/t-linux (MULTILIB_*): Disable for now.  We don't want 
	everybody to need both APCS-26 and APCS-32 libraries installed.

1998-11-25  Philip Blundell  <pb@nexus.co.uk>

	* config/arm/elf.h (MAX_OFILE_ALIGNMENT): Define here.
	(ASM_FILE_START): Add .file directive.

1998-11-24  Philip Blundell  <pb@nexus.co.uk>

	* config/arm/linux-elf.h: Turn on DWARF2 debugging tables as an
	option, but leave the default set to DBX for the time being.

	* config/arm/t-linux (LIBGCC2_CFLAGS): Add to the old value rather 
	than replacing it, in case it included -fPIC.  Include $(CROSS) so
	that the test for inhibit_libc mentioned below can work.
	(MULTILIB_DIRNAMES): Add apcs-26 versions.

	* config/arm/linux-gas.h: Move definition of inhibit_libc to ...
	* config/arm/xm-linux.h: ... here.
	
	* config/arm/linux-elf26.h (MULTILIB_DEFAULTS): Define.
	* config/arm/linux-elf.h [! SUBTARGET_DEFAULT_APCS26] 
	(MULTILIB_DEFAULTS): Likewise.

	* config/arm/linux-gas.h (CLEAR_INSN_CACHE): Correct number for
 	sys_cacheflush.
	
1998-11-23  Philip Blundell  <pb@nexus.co.uk>

	* config/arm/lib1funcs.asm: Correct name of __ELF__ symbol.

1998-11-17  Philip Blundell  <pb@nexus.co.uk>

	* crtstuff.c (__do_global_ctors_aux): Wrap extra goto in #ifdef
	__arm__ so as not to hurt other platforms.

1998-10-20  Philip Blundell  <pb@nexus.co.uk>

	* config/arm/linux-elf.h: Make -mshort-load-bytes the default.
	* config/arm/linux-elf26.h: Likewise.

	* config/arm/linux-gas.h: Define `inhibit_libc' if
	cross-compiling.

Sun Oct  4 12:39:07 1998  Philip Blundell  <philb@gnu.org>

	* config/arm/elf.h (LOCAL_LABEL_PREFIX): Set to ".".

	* configure.in: Recognise "armv2-*-linux" and use 26-bit mode as
	the default.

	* config/arm/arm.h (FUNCTION_ARG): Initial stab at passing
	floating point args in registers (if APCS_FLOAT).
	(FUNCTION_ARG_REGNO_P): Allow f0-f3 if APCS_FLOAT.

	* config/arm/linux-elf26.h: New file.

	* config/arm/linux-elf.h (LINK_SPEC): Add more flags.
	(ASM_SPEC): New macro.
	(TARGET_DEFAULT): Don't default to 32-bit mode if requested
	otherwise.
	(CPP_APCS_PC_DEFAULT_SPEC): Change to APCS-32 if appropriate.

	* config/arm/linux-gas.h (CLEAR_INSN_CACHE): New macro, currently 
	disabled (awaiting kernel support).

Sat Aug 29 18:25:33 1998  Philip Blundell  <philb@gnu.org>

	* config/arm/linux-elf.h (TARGET_DEFAULT): Make 32-bit code the
	default.

	* config/arm/lib1funcs.asm: PLT jumps are conditional on __elf__,
	not PIC.
	[L_dvmd_lnx] (__div0): Correct check for errors.

	* config/arm/linux-elf.h (LINK_SPEC): Dynamic linker lives in
 	/lib, not /lib/elf.  Add support for -rdynamic option.

Wed Aug 19 11:24:15 1998  Philip Blundell  <pb@nexus.co.uk>

	* config/arm/linux-aout.h (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE,
	WCHAR_TYPE_SIZE): Move definitions to linux-gas.h.

Sat Aug 15 22:54:14 1998  Philip Blundell  <philb@gnu.org>

	* config/arm/elf.h (ASM_OUTPUT_ADDR_DIFF_ELT): New argument BODY.

	* configure.in: For all ARM targets, match on the pattern
 	`arm*-*-..' rather than just `arm-*-...'.  Remove support for old
	and outdated `arm-*-linuxelf' configuration name.

Fri Jun  5 18:47:09 1998  Philip Blundell  <philb@gnu.org>

	* configure.in: Add support for ELF on ARM systems.

	* config/arm/elf.h: New file.  Generic ARM/ELF support.
	* config/arm/linux.h: Rename to ...
	* config/arm/linux-aout.h: ... this, and move some definitions to...
	* config/arm/linux-gas.h: ... here.  Add support for weak symbols.
	* config/arm/linux-elf.h: New file.  Support for Linux with ELF.

	* config/arm/arm.c: Various changes to PIC code generation.
	* config/arm/lib1funcs.asm: If compiling as PIC, make external
	calls PLT-relative.  Add .size and .type directives.
	* config/arm/arm.md: Added wrapper around constant pool generation
	(bMakingConstTable).  Generate PLT-relative calls when compiling
	PIC code.
	* config/arm/arm.h (SYMBOL_REF_LOCAL): Added.  We need to
	distinguish between cases that require GOT relocs and those
	that can be done with GOTOFF.
	(OUTPUT_INST_ADDR_CONST): If we're writing the constant table
	during a PIC compilation, use GOTOFF relocs.

	* crtstuff.c: Add explicit jump between sections.

	Based on patch by Pat Beirne and Scott Bambrough.
diff -u --recursive --new-file clean/egcs-1.1.1/configure.in egcs-1.1.1/configure.in
--- clean/egcs-1.1.1/configure.in	Fri Dec  4 11:33:10 1998
+++ egcs-1.1.1/configure.in	Tue Jan 12 12:47:14 1999
@@ -280,6 +280,9 @@
     alpha*-*-linux*)
       host_makefile_frag="${host_makefile_frag} config/mh-elfalphapic"
       ;;
+    arm*)
+      host_makefile_frag="${host_makefile_frag} config/mh-armpic"
+      ;;
     *)
       if test -f ${srcdir}/config/mh-${host_cpu}pic; then
         host_makefile_frag="${host_makefile_frag} config/mh-${host_cpu}pic"
@@ -915,6 +918,9 @@
       ;;
     alpha*-*-linux*)
       target_makefile_frag="${target_makefile_frag} config/mt-elfalphapic"
+      ;;
+    arm*)
+      target_makefile_frag="${target_makefile_frag} config/mt-armpic"
       ;;
     *)
       if test -f ${srcdir}/config/mt-${target_cpu}pic; then
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/arm.c egcs-1.1.1/gcc/config/arm/arm.c
--- clean/egcs-1.1.1/gcc/config/arm/arm.c	Fri Dec  4 11:33:11 1998
+++ egcs-1.1.1/gcc/config/arm/arm.c	Tue Jan 12 12:47:14 1999
@@ -24,6 +24,7 @@
 #include "config.h"
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 #include "rtl.h"
 #include "regs.h"
 #include "hard-reg-set.h"
@@ -69,6 +70,9 @@
 static void emit_sfm PROTO ((int, int));
 static enum arm_cond_code get_arm_condition_code PROTO ((rtx));
 
+/* help with managing pic data labels */
+int bMakingConstTable = 0;
+
 /*  Define the information needed to generate branch insns.  This is
    stored from the compare operation. */
 
@@ -297,6 +301,9 @@
   if (TARGET_APCS_REENT && flag_pic)
     fatal ("-fpic and -mapcs-reent are incompatible");
 
+  if (TARGET_APCS_FLOAT && TARGET_SOFT_FLOAT)
+    fatal ("-mapcs-float and -msoft-float are incompatible");
+
   if (TARGET_APCS_REENT)
     warning ("APCS reentrant code not supported.");
 
@@ -309,11 +316,10 @@
      with APCS reentrancy, since that requires too much support in the
      assembler and linker, and the ARMASM assembler seems to lack some
      required directives.  */
+#if 0
   if (flag_pic)
     warning ("Position independent code not supported");
-
-  if (TARGET_APCS_FLOAT)
-    warning ("Passing floating point arguments in fp regs not yet supported");
+#endif
 
   if (TARGET_APCS_STACK && ! TARGET_APCS)
     {
@@ -336,18 +342,28 @@
   arm_arch4 = (flags & FL_ARCH4) != 0;
   arm_thumb_aware = (flags & FL_THUMB) != 0;
 
-  if (target_fp_name)
+  if (TARGET_APCS_FLOAT)
     {
-      if (strcmp (target_fp_name, "2") == 0)
-	arm_fpu_arch = FP_SOFT2;
-      else if (strcmp (target_fp_name, "3") == 0)
-	arm_fpu_arch = FP_HARD;
-      else
-	fatal ("Invalid floating point emulation option: -mfpe=%s",
+      if (target_fp_name && strcmp (target_fp_name, "3"))
+	fatal ("-mapcs-float and -mfpe=%s are incompatible",
 	       target_fp_name);
+      arm_fpu_arch = FP_SOFT3;
     }
   else
-    arm_fpu_arch = FP_DEFAULT;
+    {
+      if (target_fp_name)
+	{
+	  if (strcmp (target_fp_name, "2") == 0)
+	    arm_fpu_arch = FP_SOFT2;
+	  else if (strcmp (target_fp_name, "3") == 0)
+	    arm_fpu_arch = FP_HARD;
+	  else
+	    fatal ("Invalid floating point emulation option: -mfpe=%s",
+		   target_fp_name);
+	}
+      else
+	arm_fpu_arch = FP_DEFAULT;
+    }
 
   if (TARGET_THUMB_INTERWORK && ! arm_thumb_aware)
     {
@@ -1182,7 +1198,7 @@
      enum machine_mode mode;
      rtx reg;
 {
-  if (GET_CODE (orig) == SYMBOL_REF)
+  if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
     {
       rtx pic_ref, address;
       rtx insn;
@@ -1210,9 +1226,14 @@
 	address = reg;
 
       emit_insn (gen_pic_load_addr (address, orig));
+      
+      /* calulate the address */
+      pic_ref = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, address);
+      
+      /* for global data (GOT based), we need to dereference this */
+      if (!SYMBOL_REF_LOCAL(orig) && GET_CODE(orig)!=LABEL_REF)
+	      pic_ref = gen_rtx (MEM, Pmode, pic_ref);
 
-      pic_ref = gen_rtx (MEM, Pmode,
-			 gen_rtx (PLUS, Pmode, pic_offset_table_rtx, address));
       RTX_UNCHANGING_P (pic_ref) = 1;
       insn = emit_move_insn (reg, pic_ref);
 #endif
@@ -1274,8 +1295,6 @@
 
       return gen_rtx (PLUS, Pmode, base, offset);
     }
-  else if (GET_CODE (orig) == LABEL_REF)
-    current_function_uses_pic_offset_table = 1;
 
   return orig;
 }
@@ -1307,6 +1326,10 @@
   start_sequence ();
   l1 = gen_label_rtx ();
 
+  /* Mark the label as frame-related, to tell flow not to consider
+     it as starting a basic block.  This is a hack.  */
+  RTX_FRAME_RELATED_P (l1) = 1;
+
   global_offset_table = gen_rtx (SYMBOL_REF, Pmode, "_GLOBAL_OFFSET_TABLE_");
   /* The PC contains 'dot'+8, but the label L1 is on the next
      instruction, so the offset is only 'dot'+4.  */
@@ -1314,10 +1337,7 @@
 		     gen_rtx (PLUS, Pmode, 
 			      gen_rtx (LABEL_REF, VOIDmode, l1),
 			      GEN_INT (4)));
-  pic_tmp2 = gen_rtx (CONST, VOIDmode,
-		      gen_rtx (PLUS, Pmode,
-			       global_offset_table,
-			       pc_rtx));
+  pic_tmp2 = gen_rtx (CONST, VOIDmode, global_offset_table);
 
   pic_rtx = gen_rtx (CONST, Pmode,
 		     gen_rtx (MINUS, Pmode, pic_tmp2, pic_tmp));
@@ -3541,6 +3561,10 @@
 	  scan = emit_insn_after (gen_consttable_8 (p->value), scan);
 	  break;
 
+	case 12:
+	  scan = emit_insn_after (gen_consttable_12 (p->value), scan);
+	  break;
+
 	default:
 	  abort ();
 	  break;
@@ -4747,7 +4771,10 @@
 
       /* Otherwise, trap an attempted return by aborting. */
       ops[0] = operand;
-      ops[1] = gen_rtx (SYMBOL_REF, Pmode, "abort");
+      if (flag_pic) 
+      	ops[1] = gen_rtx(SYMBOL_REF, Pmode, "abort(PLT)");
+      else
+	ops[1] = gen_rtx (SYMBOL_REF, Pmode, "abort");
       assemble_external_libcall (ops[1]);
       output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
       return "";
@@ -4941,7 +4968,11 @@
   /* A volatile function should never return.  Call abort.  */
   if (volatile_func)
     {
-      rtx op = gen_rtx (SYMBOL_REF, Pmode, "abort");
+      rtx op;
+      if (flag_pic)
+      	op = gen_rtx (SYMBOL_REF, Pmode, "abort(PLT)");
+      else
+      	op = gen_rtx (SYMBOL_REF, Pmode, "abort");
       assemble_external_libcall (op);
       output_asm_insn ("bl\t%a0", &op);
       goto epilogue_done;
@@ -5298,7 +5329,121 @@
   if (profile_flag || profile_block_flag)
     emit_insn (gen_blockage ());
 }
+
+/* Define where to put the arguments to a function.
+   Value is zero to push the argument on the stack,
+   or a hard register in which to store the argument.
+
+   MODE is the argument's machine mode.
+   TYPE is the data type of the argument (as a tree).
+    This is null for libcalls where that information may
+    not be available.
+   CUM is a variable of type CUMULATIVE_ARGS which gives info about
+    the preceding args and about the function being called.
+   NAMED is nonzero if this argument is a named parameter
+    (otherwise it is an extra parameter matching an ellipsis).
+
+   On the ARM, normally the first 16 bytes are passed in registers r0-r3; all
+   other arguments are passed on the stack.  If (NAMED == 0) (which happens
+   only in assign_parms, since SETUP_INCOMING_VARARGS is defined), say it is
+   passed in the stack (function_prologue will indeed make it pass in the
+   stack if necessary).  
+
+   If APCS_FLOAT is enabled, we pass the first four floating-point args in 
+   registers f0-f3. */
+struct rtx_def *
+function_arg(cum, mode, type, named)
+     CUMULATIVE_ARGS *cum;
+     enum machine_mode mode;
+     tree type;
+     int named;
+{
+  if (! named)
+    return 0;
+
+  if (TARGET_APCS_FLOAT && (GET_MODE_CLASS (mode) == MODE_FLOAT))
+    {
+      return (cum->f >= 4) ? 0 
+	: gen_rtx (REG, mode, 16 + cum->f);
+    } 
+  else
+    {
+      return (cum->g >= 16) ? 0 
+	: gen_rtx (REG, mode, (cum->g / 4));
+    }
+}
+
+/* Update the data in CUM to advance over an argument
+   of mode MODE and data type TYPE.
+   (TYPE is null for libcalls where that information may not be available.)  */
+void
+function_arg_advance(cum, mode, type, named)
+     CUMULATIVE_ARGS *cum;
+     enum machine_mode mode;
+     tree type;
+     int named;
+{
+  if (TARGET_APCS_FLOAT && (GET_MODE_CLASS (mode) == MODE_FLOAT))
+    {
+      /* Say that one more floating point arg was passed.  */
+      cum->f ++;
+    }
+  else
+    {
+      cum->g += (mode != BLKmode
+		 ? (GET_MODE_SIZE (mode) + 3) & ~3
+		 : (int_size_in_bytes (type) + 3) & ~3);
+    }
+}
+
+/* For an arg passed partly in registers and partly in memory,
+   this is the number of registers used.
+   For args passed entirely in registers or entirely in memory, zero.  */
+int
+function_arg_partial_nregs(cum, mode, type, named)
+     CUMULATIVE_ARGS *cum;
+     enum machine_mode mode;
+     tree type;
+     int named;
+{
+  /* If we pass floating point args in regs, they always fit entirely. */
+  if (TARGET_APCS_FLOAT && (GET_MODE_CLASS (mode) == MODE_FLOAT))
+    return 0;
+
+  return (cum->g < 16 && 16 < cum->g + (mode != BLKmode
+				  ? GET_MODE_SIZE (mode)
+				  : int_size_in_bytes (type))
+	  ? 4 - cum->g / 4 : 0);
+}
   
+/* Perform any actions needed for a function that is receiving a variable
+   number of arguments.  CUM is as above.  MODE and TYPE are the mode and type
+   of the current parameter.  PRETEND_SIZE is a variable that should be set to
+   the amount of stack that must be pushed by the prolog to pretend that our
+   caller pushed it.
+
+   Normally, this macro will push all remaining incoming registers on the
+   stack and set PRETEND_SIZE to the length of the registers pushed.
+
+   On the ARM, PRETEND_SIZE is set in order to have the prologue push the last
+   named arg and all anonymous args onto the stack.
+   XXX I know the prologue shouldn't be pushing registers, but it is faster
+   that way.  */
+int setup_incoming_varargs (cum, mode, type)
+     CUMULATIVE_ARGS *cum;
+     enum machine_mode mode;
+     tree type;
+{
+  int pretend;
+  extern int current_function_anonymous_args;
+  current_function_anonymous_args = 1;
+
+  if (cum->g < 16)
+    pretend = 16 - cum->g;
+
+  return pretend;
+}
+
 
 /* If CODE is 'd', then the X is a condition operand and the instruction
    should only be executed if the condition is true.
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/arm.h egcs-1.1.1/gcc/config/arm/arm.h
--- clean/egcs-1.1.1/gcc/config/arm/arm.h	Mon Aug 17 20:45:14 1998
+++ egcs-1.1.1/gcc/config/arm/arm.h	Tue Jan 12 12:47:14 1999
@@ -187,6 +187,7 @@
   %{mhard-float:%e-msoft-float and -mhard_float may not be used together} \
   -D__SOFTFP__} \
 %{!mhard-float:%{!msoft-float:%(cpp_float_default)}} \
+%{mapcs-float:-D__APCS_FLOAT__} \
 "
 
 /* Default is hard float, which doesn't define anything */
@@ -637,6 +638,8 @@
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.  */
+/* @@ Can we make R10 available when not using apcs-stack
+   or PIC?  --philb */
 #define FIXED_REGISTERS  \
 {                        \
   0,0,0,0,0,0,0,0,	 \
@@ -661,6 +664,13 @@
   1,1,1			     \
 }
 
+/* If we're making PIC, and if the SYMBOL_REF is global, we need to
+   mark it for inclusion in the GOT.  This is the default.  If the
+   SYMBOL_REF is pointing to static data/function, we can refer to it
+   without a GOT entry; this possibility is marked by setting the
+   rtx->jump bit (using the SYMBOL_REF_LOCAL macro).  */
+#define SYMBOL_REF_LOCAL(X) ((X)->jump)
+
 /* If doing stupid life analysis, avoid a bug causing a return value r0 to be
    trampled.  This effectively reduces the number of available registers by 1.
    XXX It is a hack, I know.
@@ -1021,64 +1031,56 @@
    than a word, or if they contain elements offset from zero in the struct. */
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
-/* Define where to put the arguments to a function.
-   Value is zero to push the argument on the stack,
-   or a hard register in which to store the argument.
-
-   MODE is the argument's machine mode.
-   TYPE is the data type of the argument (as a tree).
-    This is null for libcalls where that information may
-    not be available.
-   CUM is a variable of type CUMULATIVE_ARGS which gives info about
-    the preceding args and about the function being called.
-   NAMED is nonzero if this argument is a named parameter
-    (otherwise it is an extra parameter matching an ellipsis).
-
-   On the ARM, normally the first 16 bytes are passed in registers r0-r3; all
-   other arguments are passed on the stack.  If (NAMED == 0) (which happens
-   only in assign_parms, since SETUP_INCOMING_VARARGS is defined), say it is
-   passed in the stack (function_prologue will indeed make it pass in the
-   stack if necessary).  */
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)  \
-  ((NAMED)						\
-   ? ((CUM) >= 16 ? 0 : gen_rtx (REG, MODE, (CUM) / 4))	\
-   : 0)
+/* Define where to put the arguments to a function.  */
+extern struct rtx_def *function_arg ();
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)			\
+  function_arg (&CUM, MODE, TYPE, NAMED)
 
 /* For an arg passed partly in registers and partly in memory,
    this is the number of registers used.
    For args passed entirely in registers or entirely in memory, zero.  */
+extern int function_arg_partial_nregs ();
 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED)  \
-  ((CUM) < 16 && 16 < (CUM) + ((MODE) != BLKmode            \
-			       ? GET_MODE_SIZE (MODE)       \
-			       : int_size_in_bytes (TYPE))  \
-   ? 4 - (CUM) / 4 : 0)
+  function_arg_partial_nregs(&CUM, MODE, TYPE, NAMED)
 
 /* A C type for declaring a variable that is used as the first argument of
    `FUNCTION_ARG' and other related values.  For some target machines, the
    type `int' suffices and can hold the number of bytes of argument so far.
 
-   On the ARM, this is the number of bytes of arguments scanned so far.  */
-#define CUMULATIVE_ARGS  int
+   On the ARM, this is a two-element structure, one word for general
+   arguments and one for floating-point arguments.  If -mapcs-float is
+   not in effect then floating point arguments are passed in general
+   registers and the second element of the structure is ignored.  */
+struct arm_cumulative_args
+  {
+    int g;	/* bytes of general args */
+    int f;	/* number of floating-point args */
+  };
+#define CUMULATIVE_ARGS  struct arm_cumulative_args
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.
    On the ARM, the offset starts at 0.  */
 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT)  \
-  ((CUM) = (((FNTYPE) && aggregate_value_p (TREE_TYPE ((FNTYPE)))) ? 4 : 0))
+  do { \
+  (CUM).g = (((FNTYPE) && aggregate_value_p (TREE_TYPE ((FNTYPE)))) ? 4 : 0); \
+  (CUM).f = 0; \
+  } while (0)
 
 /* Update the data in CUM to advance over an argument
    of mode MODE and data type TYPE.
    (TYPE is null for libcalls where that information may not be available.)  */
+extern void function_arg_advance ();
 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)  \
-  (CUM) += ((MODE) != BLKmode                       \
-	    ? (GET_MODE_SIZE (MODE) + 3) & ~3       \
-	    : (int_size_in_bytes (TYPE) + 3) & ~3)  \
+  function_arg_advance (&CUM, MODE, TYPE, NAMED)
 
 /* 1 if N is a possible register number for function argument passing.
-   On the ARM, r0-r3 are used to pass args.  */
+   On the ARM, r0-r3 are used to pass args, as are f0-f3 when APCS_FLOAT
+   is enabled.  */
 #define FUNCTION_ARG_REGNO_P(REGNO)  \
-  ((REGNO) >= 0 && (REGNO) <= 3)
+  (((REGNO) >= 0 && (REGNO) <= 3)    \
+   || (TARGET_APCS_FLOAT && ((REGNO) >= 16 && (REGNO) <= 19)))
 
 /* Perform any actions needed for a function that is receiving a variable
    number of arguments.  CUM is as above.  MODE and TYPE are the mode and type
@@ -1093,12 +1095,14 @@
    named arg and all anonymous args onto the stack.
    XXX I know the prologue shouldn't be pushing registers, but it is faster
    that way.  */
+/* ?? Not sure what the implications are here for APCS_FLOAT.  For now,
+   do nothing.  */
 #define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL)  \
 {									\
   extern int current_function_anonymous_args;				\
   current_function_anonymous_args = 1;					\
-  if ((CUM) < 16)							\
-    (PRETEND_SIZE) = 16 - (CUM);					\
+  if ((CUM).g < 16)							\
+    (PRETEND_SIZE) = 16 - (CUM).g;					\
 }
 
 /* Generate assembly output for the start of a function.  */
@@ -1295,25 +1299,35 @@
    On the ARM, allow any integer (invalid ones are removed later by insn
    patterns), nice doubles and symbol_refs which refer to the function's
    constant pool XXX.  */
-#define LEGITIMATE_CONSTANT_P(X)	(! label_mentioned_p (X))
+#define LEGITIMATE_CONSTANT_P(X)	(flag_pic || ! label_mentioned_p (X))
 
 /* Symbols in the text segment can be accessed without indirecting via the
    constant pool; it may take an extra binary operation, but this is still
    faster than indirecting via memory.  Don't do this when not optimizing,
    since we won't be calculating al of the offsets necessary to do this
    simplification.  */
+/* patb
+   In addition, for pic, we try to determine early whether the symbol is 
+   global or static. The former need a GOT entry, the latter can use
+   a GOTOFF. The latter are marked with SYMBOL_REF_LOCAL()
+*/
 /* This doesn't work with AOF syntax, since the string table may be in
    a different AREA.  */
 #ifndef AOF_ASSEMBLER
 #define ENCODE_SECTION_INFO(decl)					\
 {									\
+  rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'   		\
+                 ? TREE_CST_RTL (decl) : DECL_RTL (decl));		\
   if (optimize > 0 && TREE_CONSTANT (decl)				\
       && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))	\
     {									\
-      rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'		\
-                 ? TREE_CST_RTL (decl) : DECL_RTL (decl));		\
       SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;				\
     }									\
+  if (flag_pic) 							\
+    {									\
+    SYMBOL_REF_LOCAL(XEXP(rtl,0))					\
+       = (TREE_CODE_CLASS(TREE_CODE(decl)) != 'd' || !TREE_PUBLIC(decl)); \
+    }									\
 }
 #endif
 
@@ -1727,8 +1741,10 @@
 
 #define FINALIZE_PIC arm_finalize_pic ()
 
-#define LEGITIMATE_PIC_OPERAND_P(X) (! symbol_mentioned_p (X))
- 
+#define LEGITIMATE_PIC_OPERAND_P(X) (! symbol_mentioned_p (X) && !label_mentioned_p (X))
+
+#define SYMBOLIC_CONST(x) (GET_CODE(x)==SYMBOL_REF || \
+	GET_CODE(x)==LABEL_REF || symbol_mentioned_p(x) || label_mentioned_p(x)) 
 
 
 /* Condition code information. */
@@ -1951,7 +1967,20 @@
   else output_addr_const(STREAM, X);					\
 }
 
+/* We need to know when we're making the constant pool; this data 
+   needs to be set GOT or GOTOFF */
+extern int bMakingConstTable;
+
 /* Handles PIC addr specially */
+/* patb  This code was inspired by the i386 version.
+	NOTE: we only do GOT dereferencing for pointer/symbols in
+	the .text segment.
+	The first "if" handles the _GLOBAL_OFFSET_TABLE_entry, and
+	the second "if" handles symbols that need (GOT) or (GOTOFF)
+  !! patb: Think the 16th/17th line of the macro, about CONSTANT_POOL_ADDRESS
+  	will never trigger, because our arm.md will never
+  	generate SYMBOL_REF int_addr which points into CONSTANT_POOL */
+
 #define OUTPUT_INT_ADDR_CONST(STREAM,X) \
   {									\
     if (flag_pic && GET_CODE(X) == CONST && is_pic(X))			\
@@ -1962,6 +1991,18 @@
 	fputs(")", STREAM);						\
       }									\
     else output_addr_const(STREAM, X);					\
+    /* do pic symbols; we only do this in the .text segment, not in .data seg */ \
+    if (flag_pic && bMakingConstTable \
+       && (GET_CODE(X) == SYMBOL_REF || GET_CODE(X) == LABEL_REF)) 	\
+    { \
+	if (GET_CODE(X)==SYMBOL_REF && CONSTANT_POOL_ADDRESS_P(X)) 	\
+		fprintf(STREAM,"(GOTOFF)"); 				\
+	else if (GET_CODE(X)==LABEL_REF) 				\
+		fprintf(STREAM,"(GOTOFF)"); 				\
+	else if (SYMBOL_REF_LOCAL(X)) 			\
+		fprintf(STREAM,"(GOTOFF)"); 		\
+	else fprintf(STREAM,"(GOT)"); 			\
+    } \
   }
 
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/arm.md egcs-1.1.1/gcc/config/arm/arm.md
--- clean/egcs-1.1.1/gcc/config/arm/arm.md	Fri Dec  4 11:33:11 1998
+++ egcs-1.1.1/gcc/config/arm/arm.md	Tue Jan 12 12:47:14 1999
@@ -2591,7 +2591,9 @@
 			   : preserve_subexpressions_p ()));
       DONE;
     }
-  if (CONSTANT_P (operands[1]) && flag_pic)
+
+  /* in PIC code, process anything involving SYMBOL_REF or LABEL_REF */
+  if (SYMBOLIC_CONST (operands[1]) && flag_pic)
     operands[1] = legitimize_pic_address (operands[1], SImode,
 					  ((reload_in_progress
 					    || reload_completed)
@@ -4229,7 +4231,16 @@
 	 (match_operand:SI 1 "general_operand" "g"))
    (clobber (reg:SI 14))]
   "GET_CODE (operands[0]) == SYMBOL_REF"
-  "bl%?\\t%a0"
+;; ScottB: February 8, 1998
+;; Changing the output control string from straight assembler generation
+;; to a C call which checks if we are generating pic code.
+;;  "bl%?\\t%a0"
+  "*
+{
+   if (flag_pic) 
+     return \"bl%?\\t%a0(PLT)\";
+   return \"bl%?\\t%a0\";
+}"
 [(set_attr "type" "call")])
 
 (define_insn "*call_value_symbol"
@@ -4238,7 +4249,16 @@
 	(match_operand:SI 2 "general_operand" "g")))
    (clobber (reg:SI 14))]
   "GET_CODE(operands[1]) == SYMBOL_REF"
-  "bl%?\\t%a1"
+;; ScottB: February 8, 1998
+;; Changing the output control string from straight assembler generation
+;; to a C call which checks if we are generating pic code.
+;;  "bl%?\\t%a1"
+  "*
+{
+   if (flag_pic) 
+     return \"bl%?\\t%a1(PLT)\";
+   return \"bl%?\\t%a1\";
+}"
 [(set_attr "type" "call")])
 
 ;; Often the return insn will be the same as loading from memory, so set attr
@@ -5969,6 +5989,10 @@
   "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
     && !get_frame_size () && !current_function_calls_alloca
     && !frame_pointer_needed && !current_function_args_size)"
+;; ScottB: February 11, 1998
+;; Changing the output control string from straight assembler generation
+;; to a C statement which checks if we are generating pic code.
+;;  return \"b%?\\t%a0\";
   "*
 {
   extern rtx arm_target_insn;
@@ -5983,6 +6007,9 @@
   }
 
   output_return_instruction (NULL, FALSE, FALSE);
+  /* ScottB: Changes made here: if (flag_pic) .... */
+  if (flag_pic) 
+    return \"b%?\\t%a0(PLT)\";
   return \"b%?\\t%a0\";
 }"
 [(set_attr "type" "call")
@@ -5997,6 +6024,10 @@
   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
     && !get_frame_size () && !current_function_calls_alloca
     && !frame_pointer_needed && !current_function_args_size)"
+;; ScottB: February 11, 1998
+;; Changing the output control string from straight assembler generation
+;; to a C statement which checks if we are generating pic code.
+;;  return \"b%?\\t%a1\";
   "*
 {
   extern rtx arm_target_insn;
@@ -6011,6 +6042,9 @@
   }
 
   output_return_instruction (NULL, FALSE, FALSE);
+  /* ScottB: Changes made here: if (flag_pic) .... */
+  if (flag_pic) 
+     return \"b%?\\t%a1(PLT)\";
   return \"b%?\\t%a1\";
 }"
 [(set_attr "type" "call")
@@ -6019,6 +6053,11 @@
 ;; As above but when this function is not void, we must be returning the
 ;; result of the called subroutine.
 
+;; ScottB: February 11, 1998
+;; This peephole definition seems to be redundant.  The comment above
+;; seems to be appropriate to the code above and below.  I was not 
+;; able to trigger this peephole optimization, only the first two.
+
 (define_peephole
   [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
 		   (call (mem:SI (match_operand:SI 1 "" "X"))
@@ -6029,6 +6068,13 @@
   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
     && !get_frame_size () && !current_function_calls_alloca
     && !frame_pointer_needed && !current_function_args_size)"
+;; ScottB: February 11, 1998
+;; Changing the output control string from straight assembler generation
+;; to a C statement which checks if we are generating pic code.
+;; Modifying this optimization, even though I have not found code to trigger
+;; it.  It seems reasonable if we are generating PIC code, that we would
+;; want to go through the PLT anyway.
+;;  return \"b%?\\t%a1\";
   "*
 {
   extern rtx arm_target_insn;
@@ -6043,6 +6089,9 @@
   }
 
   output_return_instruction (NULL, FALSE, FALSE);
+  /* ScottB: Changes made here: if (flag_pic) .... */
+  if (flag_pic) 
+     return \"b%?\\t%a1(PLT)\";
   return \"b%?\\t%a1\";
 }"
 [(set_attr "type" "call")
@@ -6210,6 +6259,7 @@
   ""
   "*
 {
+  bMakingConstTable = TRUE;
   switch (GET_MODE_CLASS (GET_MODE (operands[0])))
     {
     case MODE_FLOAT:
@@ -6232,6 +6282,7 @@
   ""
   "*
 {
+  bMakingConstTable = TRUE;
   switch (GET_MODE_CLASS (GET_MODE (operands[0])))
     {
     case MODE_FLOAT:
@@ -6249,11 +6300,35 @@
 }"
 [(set_attr "length" "8")])
 
+(define_insn "consttable_12"
+  [(unspec_volatile [(match_operand 0 "" "")] 6)]
+  ""
+  "*
+{
+  bMakingConstTable = TRUE;
+  switch (GET_MODE_CLASS (GET_MODE (operands[0])))
+    {
+    case MODE_FLOAT:
+    {
+      union real_extract u;
+      bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
+      assemble_real (u.d, GET_MODE (operands[0]));
+      break;
+    }
+    default:
+      assemble_integer (operands[0], 12, 1);
+      break;
+    }
+  return \"\";
+}"
+[(set_attr "length" "12")])
+
 (define_insn "consttable_end"
   [(unspec_volatile [(const_int 0)] 4)]
   ""
   "*
   /* Nothing to do (currently).  */
+  bMakingConstTable = FALSE;
   return \"\";
 ")
 
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/elf.h egcs-1.1.1/gcc/config/arm/elf.h
--- clean/egcs-1.1.1/gcc/config/arm/elf.h	Thu Jan  1 01:00:00 1970
+++ egcs-1.1.1/gcc/config/arm/elf.h	Tue Jan 12 12:47:14 1999
@@ -0,0 +1,545 @@
+/* Definitions of target machine for GNU compiler, for ARM with ELF
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Contributed by Philip Blundell <philb@gnu.org>
+   
+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.  */
+
+#ifndef ARM_OS_NAME
+#define ARM_OS_NAME "(generic)"
+#endif
+
+/* Biggest alignment supported by the object file format of this
+   machine.  Use this macro to limit the alignment which can be
+   specified using the `__attribute__ ((aligned (N)))' construct.  If
+   not defined, the default value is `BIGGEST_ALIGNMENT'.  */
+#define MAX_OFILE_ALIGNMENT (32768*8)
+
+/* The text to go at the start of the assembler file */
+#define ASM_FILE_START(STREAM)						    \
+{									    \
+  output_file_directive ((STREAM), main_input_filename);		    \
+  fprintf (STREAM,"%srfp\t.req\t%sr9\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+  fprintf (STREAM,"%ssl\t.req\t%sr10\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+  fprintf (STREAM,"%sfp\t.req\t%sr11\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+  fprintf (STREAM,"%sip\t.req\t%sr12\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+  fprintf (STREAM,"%ssp\t.req\t%sr13\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+  fprintf (STREAM,"%slr\t.req\t%sr14\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+  fprintf (STREAM,"%spc\t.req\t%sr15\n", REGISTER_PREFIX, REGISTER_PREFIX); \
+}
+
+#define ASM_APP_ON  ""
+#define ASM_APP_OFF  ""
+
+/* Switch to the text or data segment.  */
+#define TEXT_SECTION_ASM_OP  ".text"
+#define DATA_SECTION_ASM_OP  ".data"
+#define BSS_SECTION_ASM_OP   ".bss"
+
+#define REGISTER_PREFIX ""
+#define USER_LABEL_PREFIX ""	/* For ELF the default is no underscores */
+#define LOCAL_LABEL_PREFIX "."
+
+/* The assembler's names for the registers.  */
+#ifndef REGISTER_NAMES
+#define REGISTER_NAMES  \
+{				                   \
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",  \
+  "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc",  \
+  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",  \
+  "cc", "sfp", "afp"				   \
+}
+#endif
+
+#ifndef ADDITIONAL_REGISTER_NAMES
+#define ADDITIONAL_REGISTER_NAMES		\
+{						\
+  {"a1", 0},					\
+  {"a2", 1},					\
+  {"a3", 2},					\
+  {"a4", 3},					\
+  {"v1", 4},					\
+  {"v2", 5},					\
+  {"v3", 6},					\
+  {"v4", 7},					\
+  {"v5", 8},					\
+  {"v6", 9},					\
+  {"rfp", 9}, /* Gcc used to call it this */	\
+  {"sb", 9},					\
+  {"v7", 10},					\
+  {"r10", 10},	/* sl */			\
+  {"r11", 11},	/* fp */			\
+  {"r12", 12},	/* ip */			\
+  {"r13", 13},	/* sp */			\
+  {"r14", 14},	/* lr */			\
+  {"r15", 15}	/* pc */			\
+}
+#endif
+
+/* DBX register number for a given compiler register number */
+#define DBX_REGISTER_NUMBER(REGNO)  (REGNO)
+
+/* Generate DBX debugging information.  */
+#define DBX_DEBUGGING_INFO  1
+
+/* Output a source filename for the debugger. RISCiX dbx insists that the
+   ``desc'' field is set to compiler version number >= 315 (sic).  */
+#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(STREAM,NAME) 			\
+do {									\
+  fprintf (STREAM, ".stabs \"%s\",%d,0,315,%s\n", (NAME), N_SO,		\
+	   &ltext_label_name[1]);					\
+  text_section ();							\
+  ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0);			\
+} while (0)
+  
+/* Attach a special .ident directive to the end of the file to identify
+   the version of GCC which compiled this code.  */
+
+#define IDENT_ASM_OP ".ident"
+
+#ifdef IDENTIFY_WITH_IDENT
+#define ASM_IDENTIFY_GCC(FILE) /* nothing */
+#define ASM_IDENTIFY_LANGUAGE(FILE)			\
+ fprintf(FILE, "\t%s \"GCC (%s) %s\"\n", IDENT_ASM_OP,	\
+	 lang_identify(), version_string)
+#else
+#define ASM_FILE_END(FILE)					\
+do {				 				\
+     fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n",		\
+	      IDENT_ASM_OP, version_string);			\
+   } while (0)
+#endif
+
+/* Allow #sccs in preprocessor.  */
+
+#define SCCS_DIRECTIVE
+
+/* Output #ident as a .ident.  */
+
+#define ASM_OUTPUT_IDENT(FILE, NAME) \
+  fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME);
+
+/* imported from i386/freebsd.h  patb 10/2/98 */
+/* These macros generate the special .type and .size directives which
+   are used to set the corresponding fields of the linker symbol table
+   entries in an ELF object file under SVR4.  These macros also output
+   the starting labels for the relevant functions/objects.  */
+
+/* Write the extra assembler code needed to declare a function properly.
+   Some svr4 assemblers need to also have something extra said about the
+   function's return value.  We allow for that here.  */
+
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\
+  do {									\
+    fprintf (FILE, "\t.type\t");					\
+    assemble_name (FILE, NAME);						\
+    fprintf (FILE, ",%%function\n");					\
+    ASM_OUTPUT_LABEL(FILE, NAME);					\
+  } while (0)
+
+/* Write the extra assembler code needed to declare an object properly.  */
+
+#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)			\
+  do {									\
+    fprintf (FILE, "\t.type\t");					\
+    assemble_name (FILE, NAME);						\
+    fprintf (FILE, ",%%object\n");					\
+    size_directive_output = 0;						\
+    if (!flag_inhibit_size_directive && DECL_SIZE (DECL))		\
+      {									\
+        size_directive_output = 1;					\
+	fprintf (FILE, "\t.size\t");					\
+	assemble_name (FILE, NAME);					\
+	fprintf (FILE, ",%d\n",  int_size_in_bytes (TREE_TYPE (DECL)));	\
+      }									\
+    ASM_OUTPUT_LABEL(FILE, NAME);					\
+  } while (0)
+
+/* Output the size directive for a decl in rest_of_decl_compilation
+   in the case where we did not do so before the initializer.
+   Once we find the error_mark_node, we know that the value of
+   size_directive_output was set
+   by ASM_DECLARE_OBJECT_NAME when it was run for the same decl.  */
+
+#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)        \
+do {                                                                    \
+     char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0);                  \
+     if (!flag_inhibit_size_directive && DECL_SIZE (DECL)	        \
+         && ! AT_END && TOP_LEVEL                                       \
+         && DECL_INITIAL (DECL) == error_mark_node                      \
+         && !size_directive_output)                                     \
+       {                                                                \
+         fprintf (FILE, "\t.size\t");		                        \
+	 assemble_name (FILE, name);                                    \
+	 fprintf (FILE, ",%d\n",  int_size_in_bytes (TREE_TYPE (DECL)));\
+	}								\
+   } while (0)
+
+
+/* This is how to declare the size of a function.  */
+
+#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)			\
+  do {									\
+    if (!flag_inhibit_size_directive)					\
+      {									\
+        char label[256];						\
+	static int labelno;						\
+	labelno++;							\
+	ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);		\
+	ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno);		\
+	fprintf (FILE, "\t.size\t", SIZE_ASM_OP);				\
+	assemble_name (FILE, (FNAME));					\
+        fprintf (FILE, ", ");						\
+	assemble_name (FILE, label);					\
+        fprintf (FILE, " - ");						\
+	assemble_name (FILE, (FNAME));					\
+	putc ('\n', FILE);						\
+      }									\
+  } while (0)
+
+
+#define ASM_OUTPUT_LABEL(STREAM,NAME)	\
+do {					\
+  assemble_name (STREAM,NAME);		\
+  fputs (":\n", STREAM);		\
+} while (0)
+
+/* Output a globalising directive for a label.  */
+#define ASM_GLOBALIZE_LABEL(STREAM,NAME)  \
+  (fprintf (STREAM, "\t.global\t"),	  \
+   assemble_name (STREAM, NAME),	  \
+   fputc ('\n',STREAM))                   \
+
+/* Make an internal label into a string.  */
+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM)  \
+  sprintf (STRING, "*%s%s%d", LOCAL_LABEL_PREFIX, PREFIX, NUM)
+
+/* Nothing special is done about jump tables */
+/* #define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE)   */
+/* #define ASM_OUTPUT_CASE_END(STREAM,NUM,TABLE)	    */
+#define JUMP_TABLES_IN_TEXT_SECTION 1
+
+/* Construct a private name.  */
+#define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER)  \
+  ((OUTVAR) = (char *) alloca (strlen (NAME) + 10),  \
+   sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)))
+
+/* Output an element of a dispatch table.  */
+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE)  \
+   fprintf (STREAM, "\t.word\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE)
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL)  \
+   fprintf (STREAM, "\tb\t%sL%d\n", LOCAL_LABEL_PREFIX, (VALUE))
+
+/* Output various types of constants.  For real numbers we output hex, with
+   a comment containing the "human" value, this allows us to pass NaN's which
+   the riscix assembler doesn't understand (it also makes cross-assembling
+   less likely to fail). */
+
+#define ASM_OUTPUT_LONG_DOUBLE(STREAM,VALUE)				\
+do { char dstr[30];							\
+     long l[3];								\
+     REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l);			\
+     REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);			\
+     fprintf (STREAM, "\t.long 0x%lx,0x%lx,0x%lx\t%s long double %s\n", \
+	      l[0], l[1], l[2], ASM_COMMENT_START, dstr);		\
+   } while (0)
+
+    
+#define ASM_OUTPUT_DOUBLE(STREAM, VALUE)  				\
+do { char dstr[30];							\
+     long l[2];								\
+     REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l);				\
+     REAL_VALUE_TO_DECIMAL (VALUE, "%.14g", dstr);			\
+     fprintf (STREAM, "\t.long 0x%lx, 0x%lx\t%s double %s\n", l[0],	\
+	      l[1], ASM_COMMENT_START, dstr);				\
+   } while (0)
+
+#define ASM_OUTPUT_FLOAT(STREAM, VALUE)					\
+do { char dstr[30];							\
+     long l;								\
+     REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);				\
+     REAL_VALUE_TO_DECIMAL (VALUE, "%.7g", dstr);			\
+     fprintf (STREAM, "\t.word 0x%lx\t%s float %s\n", l,		\
+	      ASM_COMMENT_START, dstr);					\
+   } while (0);
+
+#define ASM_OUTPUT_INT(STREAM, EXP)		\
+  {						\
+    fprintf (STREAM, "\t.word\t");		\
+    OUTPUT_INT_ADDR_CONST (STREAM, (EXP));	\
+    fprintf (STREAM, "\n");			\
+  }
+
+#define ASM_OUTPUT_SHORT(STREAM, EXP)  \
+  (fprintf (STREAM, "\t.short\t"),     \
+   output_addr_const (STREAM, (EXP)),  \
+   fputc ('\n', STREAM))
+
+#define ASM_OUTPUT_CHAR(STREAM, EXP)  \
+  (fprintf (STREAM, "\t.byte\t"),      \
+   output_addr_const (STREAM, (EXP)),  \
+   fputc ('\n', STREAM))
+
+#define ASM_OUTPUT_BYTE(STREAM, VALUE)  \
+  fprintf (STREAM, "\t.byte\t%d\n", VALUE)
+
+#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN)  \
+  output_ascii_pseudo_op ((STREAM), (unsigned char *)(PTR), (LEN))
+
+/* Output a gap.  In fact we fill it with nulls.  */
+#define ASM_OUTPUT_SKIP(STREAM, NBYTES)  \
+   fprintf (STREAM, "\t.space\t%d\n", NBYTES)
+
+/* Align output to a power of two.  Horrible /bin/as.  */
+#define ASM_OUTPUT_ALIGN(STREAM, POWER)  \
+   fprintf (STREAM, "\t.align\t%d\n", POWER)
+
+/* Output a common block */
+#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED)  		\
+  (fprintf (STREAM, "\t.comm\t"), 		     			\
+   assemble_name ((STREAM), (NAME)),		     			\
+   fprintf(STREAM, ", %d\t%s %d\n", ROUNDED, ASM_COMMENT_START, SIZE))
+
+/* Output a local common block.  /bin/as can't do this, so hack a
+   `.space' into the bss segment.  Note that this is *bad* practice.  */
+#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM,NAME,SIZE,ALIGN)		\
+  do {									\
+    bss_section ();							\
+    ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT));	\
+    ASM_OUTPUT_LABEL (STREAM, NAME);					\
+    fprintf (STREAM, "\t.space\t%d\n", SIZE);				\
+  } while (0)
+
+/* Output a zero-initialized block.  */
+#define ASM_OUTPUT_ALIGNED_BSS(STREAM,DECL,NAME,SIZE,ALIGN) \
+  asm_output_aligned_bss(STREAM, DECL, NAME, SIZE, ALIGN)
+
+/* Output a source line for the debugger.  */
+/* #define ASM_OUTPUT_SOURCE_LINE(STREAM,LINE) */
+
+/* The assembler's parentheses characters.  */
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+#ifndef ASM_COMMENT_START
+#define ASM_COMMENT_START "@"
+#endif
+
+/* This works for GAS and some other assemblers.  */
+#define SET_ASM_OP	".set"
+
+/* Support const sections and the ctors and dtors sections for g++.
+   Note that there appears to be two different ways to support const
+   sections at the moment.  You can either #define the symbol
+   READONLY_DATA_SECTION (giving it some code which switches to the
+   readonly data section) or else you can #define the symbols
+   EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and
+   SELECT_RTX_SECTION.  We do both here just to be on the safe side.  */
+
+#define USE_CONST_SECTION	1
+
+#define CONST_SECTION_ASM_OP	".section\t.rodata"
+
+/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
+
+   Note that we want to give these sections the SHF_WRITE attribute
+   because these sections will actually contain data (i.e. tables of
+   addresses of functions in the current root executable or shared library
+   file) and, in the case of a shared library, the relocatable addresses
+   will have to be properly resolved/relocated (and then written into) by
+   the dynamic linker when it actually attaches the given shared library
+   to the executing process.  (Note that on SVR4, you may wish to use the
+   `-z text' option to the ELF linker, when building a shared library, as
+   an additional check that you are doing everything right.  But if you do
+   use the `-z text' option when building a shared library, you will get
+   errors unless the .ctors and .dtors sections are marked as writable
+   via the SHF_WRITE attribute.)  */
+
+#define CTORS_SECTION_ASM_OP	".section\t.ctors,\"aw\""
+#define DTORS_SECTION_ASM_OP	".section\t.dtors,\"aw\""
+
+/* On svr4, we *do* have support for the .init and .fini sections, and we
+   can put stuff in there to be executed before and after `main'.  We let
+   crtstuff.c and other files know this by defining the following symbols.
+   The definitions say how to change sections to the .init and .fini
+   sections.  This is the same for all known svr4 assemblers.  */
+
+#define INIT_SECTION_ASM_OP	".section\t.init"
+#define FINI_SECTION_ASM_OP	".section\t.fini"
+
+/* 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_const, 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						\
+  CONST_SECTION_FUNCTION						\
+  CTORS_SECTION_FUNCTION						\
+  DTORS_SECTION_FUNCTION
+
+#undef READONLY_DATA_SECTION
+#define READONLY_DATA_SECTION() const_section ()
+
+extern void text_section ();
+
+#define CONST_SECTION_FUNCTION						\
+void									\
+const_section ()							\
+{									\
+  if (!USE_CONST_SECTION)						\
+    text_section();							\
+  else if (in_section != in_const)					\
+    {									\
+      fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP);		\
+      in_section = in_const;						\
+    }									\
+}
+
+#define CTORS_SECTION_FUNCTION						\
+void									\
+ctors_section ()							\
+{									\
+  if (in_section != in_ctors)						\
+    {									\
+      fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP);		\
+      in_section = in_ctors;						\
+    }									\
+}
+
+#define DTORS_SECTION_FUNCTION						\
+void									\
+dtors_section ()							\
+{									\
+  if (in_section != in_dtors)						\
+    {									\
+      fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP);		\
+      in_section = in_dtors;						\
+    }									\
+}
+
+/* Switch into a generic section.
+   This is currently only used to support section attributes.
+
+   We make the section read-only and executable for a function decl,
+   read-only for a const data decl, and writable for a non-const data decl.  */
+#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
+  fprintf (FILE, ".section\t%s,\"%s\",%%progbits\n", NAME, \
+	   (DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \
+	   (DECL) && DECL_READONLY_SECTION (DECL, RELOC) ? "a" : "aw")
+
+
+#define INT_ASM_OP		".word"
+
+/* A C statement (sans semicolon) to output an element in the table of
+   global constructors.  */
+#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.  */
+#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)
+
+/* A C statement or statements to switch to the appropriate
+   section for output of DECL.  DECL is either a `VAR_DECL' node
+   or a constant of some sort.  RELOC indicates whether forming
+   the initial value of DECL requires link-time relocations.  */
+
+#define SELECT_SECTION(DECL,RELOC)					\
+{									\
+  if (TREE_CODE (DECL) == STRING_CST)					\
+    {									\
+      if (! flag_writable_strings)					\
+	const_section ();						\
+      else								\
+	data_section ();						\
+    }									\
+  else if (TREE_CODE (DECL) == VAR_DECL)				\
+    {									\
+      if ((flag_pic && RELOC)						\
+	  || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL)		\
+	  || !DECL_INITIAL (DECL)					\
+	  || (DECL_INITIAL (DECL) != error_mark_node			\
+	      && !TREE_CONSTANT (DECL_INITIAL (DECL))))			\
+	data_section ();						\
+      else								\
+	const_section ();						\
+    }									\
+  else									\
+    const_section ();							\
+}
+
+/* A C statement or statements to switch to the appropriate
+   section for output of RTX in mode MODE.  RTX is some kind
+   of constant in RTL.  The argument MODE is redundant except
+   in the case of a `const_int' rtx.  Currently, these always
+   go into the const section.  */
+
+#undef SELECT_RTX_SECTION
+#define SELECT_RTX_SECTION(MODE,RTX) const_section()
+
+/* Define the strings used for the special svr4 .type and .size directives.
+   These strings generally do not vary from one system running svr4 to
+   another, but if a given system (e.g. m88k running svr) needs to use
+   different pseudo-op names for these, they may be overridden in the
+   file which includes this one.  */
+
+#define TYPE_ASM_OP	".type"
+#define SIZE_ASM_OP	".size"
+
+/* This is how we tell the assembler that a symbol is weak.  */
+
+#define ASM_WEAKEN_LABEL(FILE,NAME) \
+  do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \
+       fputc ('\n', FILE); } while (0)
+
+/* This is how we tell the assembler that two symbols have the same value.  */
+
+#define ASM_OUTPUT_DEF(FILE,NAME1,NAME2) \
+  do { assemble_name(FILE, NAME1); 	 \
+       fputs(" = ", FILE);		 \
+       assemble_name(FILE, NAME2);	 \
+       fputc('\n', FILE); } while (0)
+
+/* The following macro defines the format used to output the second
+   operand of the .type assembler directive.  Different svr4 assemblers
+   expect various different forms for this operand.  The one given here
+   is just a default.  You may need to override it in your machine-
+   specific tm.h file (depending upon the particulars of your assembler).  */
+
+#define TYPE_OPERAND_FMT	"%%%s"
+
+#include "arm/arm.h"
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/lib1funcs.asm egcs-1.1.1/gcc/config/arm/lib1funcs.asm
--- clean/egcs-1.1.1/gcc/config/arm/lib1funcs.asm	Wed Apr  1 18:18:58 1998
+++ egcs-1.1.1/gcc/config/arm/lib1funcs.asm	Tue Jan 12 12:47:14 1999
@@ -43,6 +43,12 @@
 #define RETCOND
 #endif
 
+#ifdef __ELF__
+#define __PLT__ (PLT)
+#else
+#define __PLT__
+#endif
+
 #ifndef __USER_LABEL_PREFIX__
 #define __USER_LABEL_PREFIX__ _
 #endif
@@ -66,9 +72,11 @@
 sp		.req	r13
 lr		.req	r14
 pc		.req	r15
+
 	.text
-	.globl SYM (__udivsi3)
-	.align 0
+	.globl	SYM(__udivsi3)
+	.type 	SYM(__udivsi3),%function
+	.align	0
 
 SYM (__udivsi3):
 	cmp	divisor, #0
@@ -124,10 +132,12 @@
 
 Ldiv0:
 	str	lr, [sp, #-4]!
-	bl	SYM (__div0)
+	bl	SYM (__div0) __PLT__
 	mov	r0, #0			@ about as wrong as it could be
 	ldmia	sp!, {pc}RETCOND
 
+	.size	SYM(__udivsi3), . - SYM(__udivsi3)
+
 #endif /* L_udivsi3 */
 
 #ifdef L_umodsi3
@@ -142,6 +152,7 @@
 pc		.req	r15
 	.text
 	.globl SYM (__umodsi3)
+	.type SYM (__umodsi3),%function
 	.align 0
 
 SYM (__umodsi3):
@@ -210,10 +221,12 @@
 
 Ldiv0:
 	str	lr, [sp, #-4]!
-	bl	SYM (__div0)
+	bl	SYM (__div0) __PLT__
 	mov	r0, #0			@ about as wrong as it could be
 	ldmia	sp!, {pc}RETCOND
 
+	.size	SYM(__umodsi3), . - SYM(__umodsi3)
+
 #endif /* L_umodsi3 */
 
 #ifdef L_divsi3
@@ -228,6 +241,7 @@
 pc		.req	r15
 	.text
 	.globl SYM (__divsi3)
+	.type SYM (__divsi3),%function
 	.align 0
 
 SYM (__divsi3):
@@ -291,10 +305,12 @@
 
 Ldiv0:
 	str	lr, [sp, #-4]!
-	bl	SYM (__div0)
+	bl	SYM (__div0) __PLT__
 	mov	r0, #0			@ about as wrong as it could be
 	ldmia	sp!, {pc}RETCOND
 
+	.size	SYM(__divsi3), . - SYM(__divsi3)
+
 #endif /* L_divsi3 */
 
 #ifdef L_modsi3
@@ -309,6 +325,7 @@
 pc		.req	r15
 	.text
 	.globl SYM (__modsi3)
+	.type SYM (__modsi3),%function
 	.align 0
 
 SYM (__modsi3):
@@ -388,18 +405,22 @@
 
 Ldiv0:
 	str	lr, [sp, #-4]!
-	bl	SYM (__div0)
+	bl	SYM (__div0) __PLT__
 	mov	r0, #0			@ about as wrong as it could be
 	ldmia	sp!, {pc}RETCOND
 
+	.size	SYM(__modsi3), . - SYM(__modsi3)
+
 #endif /* L_modsi3 */
 
 #ifdef L_dvmd_tls
 
 	.globl SYM (__div0)
+	.type SYM(__div0),%function
 	.align 0
 SYM (__div0):
 	RET	pc, lr
+	.size	SYM(__div0), . - SYM(__div0)
 
 #endif /* L_divmodsi_tools */
 
@@ -407,18 +428,20 @@
 @ GNU/Linux division-by zero handler.  Used in place of L_dvmd_tls
 
 #include <asm/unistd.h>
-#define SIGFPE	8			@ cant use <asm/signal.h> as it
-					@ contains too much C rubbish
+#define SIGFPE	8
+
 	.globl SYM (__div0)
+	.type SYM(__div0),%function
 	.align 0
 SYM (__div0):
 	stmfd	sp!, {r1, lr}
 	swi	__NR_getpid
 	cmn	r0, #1000
-	ldmgefd	sp!, {r1, pc}RETCOND	@ not much we can do
+	ldmhsfd	sp!, {r1, pc}RETCOND	@ not much we can do
 	mov	r1, #SIGFPE
 	swi	__NR_kill
 	ldmfd	sp!, {r1, pc}RETCOND
+	.size 	SYM(__div0), . - SYM(__div0)
 
 #endif /* L_dvmd_lnx */
 
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/linux-aout.h egcs-1.1.1/gcc/config/arm/linux-aout.h
--- clean/egcs-1.1.1/gcc/config/arm/linux-aout.h	Thu Jan  1 01:00:00 1970
+++ egcs-1.1.1/gcc/config/arm/linux-aout.h	Tue Jan 12 12:47:14 1999
@@ -0,0 +1,58 @@
+/* Definitions for ARM running Linux-based GNU systems using a.out.
+   Copyright (C) 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
+   Contributed by Russell King  <rmk92@ecs.soton.ac.uk>.
+
+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 this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include <linux-aout.h>
+
+/* these are different... */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+"%{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}} %{static:-static}"
+
+#undef ASM_APP_ON
+#undef ASM_APP_OFF
+#undef COMMENT_BEGIN
+ 
+/* We default to ARM3.  */
+#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm3
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES \
+"-Dunix -Darm -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(arm) -Amachine(arm)"
+
+#undef LIB_SPEC
+#define LIB_SPEC \
+	"%{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} %{!ggdb:-lc} %{ggdb:-lg}"
+
+#define HANDLE_SYSV_PRAGMA
+  
+/* Run-time Target Specification.  */
+#define TARGET_VERSION  fputs (" (ARM GNU/Linux with a.out)", stderr);
+
+/* 
+ * Maths operation domain error number, EDOM
+ * We don't really want this for libc6.  However, taking it out would be
+ * too much of a pain for now and it doesn't hurt much.
+ */
+#define TARGET_EDOM 33
+
+#include "arm/aout.h"
+
+#include "arm/linux-gas.h"
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/linux-elf.h egcs-1.1.1/gcc/config/arm/linux-elf.h
--- clean/egcs-1.1.1/gcc/config/arm/linux-elf.h	Thu Jan  1 01:00:00 1970
+++ egcs-1.1.1/gcc/config/arm/linux-elf.h	Tue Jan 12 12:47:15 1999
@@ -0,0 +1,101 @@
+/* Definitions for ARM running Linux-based GNU systems using ELF
+   Copyright (C) 1993, 1994, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Contributed by Philip Blundell <philb@gnu.org>
+
+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 this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Run-time Target Specification.  */
+#define TARGET_VERSION  fputs (" (ARM GNU/Linux with ELF)", stderr);
+
+/* we have libgcc2 */
+#define HAVE_ATEXIT
+
+/* Default is to use APCS-32 mode.  */
+#ifndef SUBTARGET_DEFAULT_APCS26
+#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_SHORT_BYTE)
+#define MULTILIB_DEFAULTS   { "mapcs-32" }
+#define SUBTARGET_EXTRA_LINK_SPEC	\
+	" %{mapcs-26:-m elf32arm26} %{!mapcs-26:-m elf32arm}"
+#define SUBTARGET_EXTRA_ASM_SPEC	\
+	" %{mapcs-26:-mapcs-26} %(!mapcs-26:-mapcs-32}"
+#endif
+
+/* This was defined in linux.h.  Define it here also. */
+#undef DEFAULT_VTABLE_THUNKS
+#define DEFAULT_VTABLE_THUNKS   1
+
+/* Handle #pragma weak and #pragma pack.  */
+#define HANDLE_SYSV_PRAGMA
+
+/* Now we define the strings used to build the spec file */
+
+#define ASM_SPEC "%{mbig-endian:-EB} %{mapcs-float:-mfloat} "
+/* we don't need an ASM_FINAL_SPEC */
+
+#define LIB_SPEC \
+  "%{shared: -lc} \
+   %{!shared: %{pthread:-lpthread} \
+	%{profile:-lc_p} %{!profile: -lc}}"
+
+#define LIBGCC_SPEC "%{msoft-float:-lfloat} -lgcc"
+
+/* add the compiler's crtend, and the library's crtn */
+#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} \
+   %{pg:gcrtn.o%s}%{!pg:crtn.o%s}"
+
+#define STARTFILE_SPEC "%{!shared:crt1.o%s} \
+   crti.o%s \
+   %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+
+#define LINK_SPEC "%{h*} %{version:-v} \
+   %{b} %{Wl,*:%*} \
+   %{static:-Bstatic} \
+   %{shared:-shared} \
+   %{symbolic:-Bsymbolic} \
+   %{rdynamic:-export-dynamic} \
+   %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2} \
+   -X \
+   %{mbig-endian:-EB}" \
+   SUBTARGET_EXTRA_LINK_SPEC
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES \
+"-Dunix -Darm -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(arm) \
+-Amachine(arm) -D__ELF__"
+
+#include "arm/elf.h"   /* macros to issue to the assembler */
+
+#include "arm/linux-gas.h"
+
+#ifndef SUBTARGET_DEFAULT_APCS26
+#undef CPP_APCS_PC_DEFAULT_SPEC
+#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
+/* On 32-bit machine it is always safe to assume we have the "new"
+   floating point system.  */
+#undef FP_DEFAULT
+#define FP_DEFAULT FP_SOFT3
+#endif
+
+#ifndef OBJECT_FORMAT_ELF
+#define OBJECT_FORMAT_ELF
+#endif
+
+/* Make DWARF2 an option, but keep DBX as the default for now.
+   Use -gdwarf2 to turn on DWARF2.  */
+#define DWARF2_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/linux-elf26.h egcs-1.1.1/gcc/config/arm/linux-elf26.h
--- clean/egcs-1.1.1/gcc/config/arm/linux-elf26.h	Thu Jan  1 01:00:00 1970
+++ egcs-1.1.1/gcc/config/arm/linux-elf26.h	Tue Jan 12 12:47:15 1999
@@ -0,0 +1,34 @@
+/* Definitions for 26-bit ARM running Linux-based GNU systems using ELF
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   Contributed by Philip Blundell <philb@gnu.org>
+
+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 this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define SUBTARGET_DEFAULT_APCS26
+
+#define MULTILIB_DEFAULTS   { "mapcs-26" }
+
+#define SUBTARGET_EXTRA_LINK_SPEC	\
+	" %{mapcs-32:-m elf32arm} %{!mapcs-32:-m elf32arm26}"
+
+#define SUBTARGET_EXTRA_ASM_SPEC	\
+	" %{mapcs-32:-mapcs-32} %(!mapcs-32:-mapcs-26}"
+
+#define TARGET_DEFAULT (ARM_FLAG_SHORT_BYTE)
+
+#include "arm/linux-elf.h"
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/linux-gas.h egcs-1.1.1/gcc/config/arm/linux-gas.h
--- clean/egcs-1.1.1/gcc/config/arm/linux-gas.h	Sat Dec  6 17:24:36 1997
+++ egcs-1.1.1/gcc/config/arm/linux-gas.h	Tue Jan 12 12:47:15 1999
@@ -1,7 +1,8 @@
 /* Definitions of target machine for GNU compiler.  ARM Linux-based GNU
    systems version.
-   Copyright (C) 1997 Free Software Foundation, Inc.
-   Contributed by Russell King  <rmk92@ecs.soton.ac.uk>.
+   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Contributed by Russell King  <rmk92@ecs.soton.ac.uk>
+   and Philip Blundell <philb@gnu.org>
 
 This file is part of GNU CC.
 
@@ -20,11 +21,6 @@
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-/* Limit the length of a stabs entry (for the broken Acorn assembler) */
-#define DBX_CONTIN_LENGTH 80
-
-#include "arm/linux.h"
-
 /*
  * We are using GAS, so stabs should work.
  */
@@ -32,3 +28,59 @@
 #ifndef DBX_DEBUGGING_INFO
 #define DBX_DEBUGGING_INFO 1
 #endif
+
+/*
+ * This is how we tell the assembler that a symbol is weak.  GAS always
+ * supports weak symbols.
+ */
+
+#define ASM_WEAKEN_LABEL(FILE,NAME) \
+  do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \
+       fputc ('\n', FILE); } while (0)
+
+/* This is used in ASM_FILE_START */
+#undef ARM_OS_NAME
+#define ARM_OS_NAME "Linux"
+
+/* Unsigned chars produces much better code than signed.  */
+#define DEFAULT_SIGNED_CHAR 0
+
+#undef SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC  "%{posix:-D_POSIX_SOURCE} %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__}"
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+/* Emit code to set up a trampoline and synchronise the caches.  */
+
+#undef INITIALIZE_TRAMPOLINE
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)			\
+{									\
+  emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 8)),	\
+		  (CXT));						\
+  emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 12)),	\
+		  (FNADDR));						\
+  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),	\
+		     0, VOIDmode, 2, TRAMP, Pmode,			\
+		     plus_constant (TRAMP, TRAMPOLINE_SIZE), Pmode);	\
+}
+
+/* Clear the instruction cache from `beg' to `end'.  This makes an
+   inline system call to SYS_cacheflush.  */
+
+#define CLEAR_INSN_CACHE(BEG, END)					\
+{									\
+  register unsigned long _beg __asm ("a1") = (unsigned long) (BEG);	\
+  register unsigned long _end __asm ("a2") = (unsigned long) (END);	\
+  register unsigned long _flg __asm ("a3") = 0;				\
+  __asm __volatile ("swi 0x9f0002");					\
+}
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/linux.h egcs-1.1.1/gcc/config/arm/linux.h
--- clean/egcs-1.1.1/gcc/config/arm/linux.h	Sat Dec  6 17:24:37 1997
+++ egcs-1.1.1/gcc/config/arm/linux.h	Thu Jan  1 01:00:00 1970
@@ -1,72 +0,0 @@
-/* Definitions for ARM running Linux-based GNU systems.
-   Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
-   Contributed by Russell King  <rmk92@ecs.soton.ac.uk>.
-
-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 this program; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#include <linux-aout.h>
-
-/* these are different... */
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
-"%{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}} %{static:-static}"
-
-#undef ASM_APP_ON
-#undef ASM_APP_OFF
-#undef COMMENT_BEGIN
- 
-/* We default to ARM3.  */
-#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm3
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES \
-"-Dunix -Darm -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(arm) -Amachine(arm)"
-
-#undef LIB_SPEC
-#define LIB_SPEC \
-	"%{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} %{!ggdb:-lc} %{ggdb:-lg}"
-
-#undef SIZE_TYPE
-#define SIZE_TYPE "unsigned int"
-
-#undef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "int"
-
-#undef WCHAR_TYPE
-#define WCHAR_TYPE "long int"
-
-#undef WCHAR_TYPE_SIZE
-#define WCHAR_TYPE_SIZE BITS_PER_WORD
-
-#define HANDLE_SYSV_PRAGMA
-  
-/* Run-time Target Specification.  */
-#define TARGET_VERSION  fputs (" (ARM GNU/Linux with a.out)", stderr);
-
-/* This is used in ASM_FILE_START */
-#define ARM_OS_NAME "Linux"
-
-/* Unsigned chars produces much better code than signed.  */
-#define DEFAULT_SIGNED_CHAR 0
-
-/* Maths operation domain error number, EDOM */
-#define TARGET_EDOM 33
-#include "arm/aout.h"
-
-#undef SUBTARGET_CPP_SPEC
-#define SUBTARGET_CPP_SPEC  "%{posix:-D_POSIX_SOURCE}"
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/t-linux egcs-1.1.1/gcc/config/arm/t-linux
--- clean/egcs-1.1.1/gcc/config/arm/t-linux	Sat Dec  6 17:24:39 1997
+++ egcs-1.1.1/gcc/config/arm/t-linux	Tue Jan 12 12:47:15 1999
@@ -1,6 +1,6 @@
 # Just for these, we omit the frame pointer since it makes such a big
 # difference.  It is then pointless adding debugging.
-LIBGCC2_CFLAGS=-O2 -fomit-frame-pointer $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -g0
+LIBGCC2_CFLAGS = -O2 -fomit-frame-pointer $(TARGET_LIBGCC2_CFLAGS) $(CROSS) $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -g0
 
 # Don't build enquire
 ENQUIRE=
@@ -12,8 +12,8 @@
 LIB1ASMSRC = arm/lib1funcs.asm
 LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
 
-MULTILIB_OPTIONS = mapcs-32
-MULTILIB_DIRNAMES = apcs-32
+#MULTILIB_OPTIONS = mapcs-32/mapcs-26
+#MULTILIB_DIRNAMES = apcs-32 apcs-26
 
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config/arm/xm-linux.h egcs-1.1.1/gcc/config/arm/xm-linux.h
--- clean/egcs-1.1.1/gcc/config/arm/xm-linux.h	Sat Dec  6 17:24:41 1997
+++ egcs-1.1.1/gcc/config/arm/xm-linux.h	Tue Jan 12 12:47:15 1999
@@ -22,3 +22,7 @@
 #include <arm/xm-arm.h>
 #include <xm-linux.h>
 
+/* If cross-compiling, don't require stdio.h etc to build libgcc.a.  */
+#ifdef CROSS_COMPILE
+#define inhibit_libc
+#endif
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/config.sub egcs-1.1.1/gcc/config.sub
--- clean/egcs-1.1.1/gcc/config.sub	Sat Apr  4 18:37:36 1998
+++ egcs-1.1.1/gcc/config.sub	Tue Jan 12 12:47:15 1999
@@ -175,7 +175,7 @@
 		;;
 	# Recognize the basic CPU types with company name.
 	vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
-	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm*-* | c[123]* \
 	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
 	      | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
 	      | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/configure.in egcs-1.1.1/gcc/configure.in
--- clean/egcs-1.1.1/gcc/configure.in	Fri Aug 28 01:19:04 1998
+++ egcs-1.1.1/gcc/configure.in	Tue Jan 12 12:47:15 1999
@@ -511,16 +511,36 @@
 		# On NetBSD, the headers are already okay, except for math.h.
 		fixincludes=fixinc.wrap
 		;;
-	arm-*-linux-gnuaout*)		# ARM GNU/Linux
+	arm*-*-linux-gnuaout*)		# ARM GNU/Linux with a.out
 		cpu_type=arm
 		xmake_file=x-linux
-		tm_file=arm/linux-gas.h
+		tm_file=arm/linux-aout.h
 		tmake_file=arm/t-linux
 		fixincludes=Makefile.in
 		gnu_ld=yes
 		;;
-	arm-*-aout)
+	arm*-*-linux-gnu*)		# ARM GNU/Linux with ELF
+		xm_file=arm/xm-linux.h
+		xmake_file=x-linux
+		case $machine in
+		armv2*-*-*)
+			tm_file=arm/linux-elf26.h
+			;;
+		*)
+			tm_file=arm/linux-elf.h
+			;;
+		esac
+		tmake_file="t-linux arm/t-linux"
+		extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+		fixincludes=Makefile.in		# Nothing to fix
+		gnu_ld=yes
+		;;
+	arm*-*-aout)
 		tm_file=arm/aout.h
+		tmake_file=arm/t-bare
+		;;
+	arm*-*-elf)
+		tm_file=arm/elf.h
 		tmake_file=arm/t-bare
 		;;
 	c1-convex-*)			# Convex C1
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/crtstuff.c egcs-1.1.1/gcc/crtstuff.c
--- clean/egcs-1.1.1/gcc/crtstuff.c	Mon Jun  8 19:30:12 1998
+++ egcs-1.1.1/gcc/crtstuff.c	Tue Jan 12 12:47:15 1999
@@ -230,8 +230,11 @@
 #ifdef FORCE_INIT_SECTION_ALIGN
   FORCE_INIT_SECTION_ALIGN;	/* Explicit align before switch to .text */
 #endif
+#ifdef __arm__
+goto L1;
+#endif
   asm (TEXT_SECTION_ASM_OP);	/* don't put epilogue and body in .init */
-  DO_GLOBAL_CTORS_BODY;
+L1:  DO_GLOBAL_CTORS_BODY;
   ON_EXIT (__do_global_dtors, 0);
 }
 
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/flow.c egcs-1.1.1/gcc/flow.c
--- clean/egcs-1.1.1/gcc/flow.c	Wed Jul  8 22:15:55 1998
+++ egcs-1.1.1/gcc/flow.c	Tue Jan 12 12:47:15 1999
@@ -485,8 +485,12 @@
 	  /* Make a list of all labels referred to other than by jumps.  */
 	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
 	    if (REG_NOTE_KIND (note) == REG_LABEL)
-	      label_value_list = gen_rtx_EXPR_LIST (VOIDmode, XEXP (note, 0),
-						    label_value_list);
+	      {
+		rtx lab = XEXP (note, 0);
+		if (! RTX_FRAME_RELATED_P (lab))
+		  label_value_list = gen_rtx_EXPR_LIST (VOIDmode, lab,
+							label_value_list);
+	      }
 	}
 
       /* Keep a lifo list of the currently active exception notes.  */
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/reload1.c egcs-1.1.1/gcc/reload1.c
--- clean/egcs-1.1.1/gcc/reload1.c	Thu Aug 27 23:48:14 1998
+++ egcs-1.1.1/gcc/reload1.c	Wed Jan 13 10:07:48 1999
@@ -5721,7 +5721,18 @@
 			  for (i1 = 0; i1 < n_earlyclobbers; i1++)
 			    if (reg_overlap_mentioned_for_reload_p
 				(reg_last_reload_reg[regno],
-				 reload_earlyclobbers[i1]))
+				 reload_earlyclobbers[i1])
+				/* If this reload is an input tied to
+				   an earlyclobber output and there
+				   are other reloads for this insn,
+				   then inheriting this reload might
+				   clobber other reloaded inputs.
+				   Detecting this while scanning the
+				   other reloads is hard, so don't
+				   inherit the reload in this rare
+				   case. */
+				|| (reload_earlyclobbers[i1] == reload_out[r]
+				    && n_reloads > 1))
 			      break;
 
 			  if (i1 != n_earlyclobbers
diff -u --recursive --new-file clean/egcs-1.1.1/gcc/rtl.h egcs-1.1.1/gcc/rtl.h
--- clean/egcs-1.1.1/gcc/rtl.h	Mon Jul 13 04:34:12 1998
+++ egcs-1.1.1/gcc/rtl.h	Tue Jan 12 12:47:15 1999
@@ -165,7 +165,10 @@
   unsigned integrated : 1;
   /* Nonzero if this rtx is related to the call frame, either changing how
      we compute the frame address or saving and restoring registers in
-     the prologue and epilogue.  */
+     the prologue and epilogue.
+     1 in a CODE_LABEL if this label is only used as part of the prologue.
+     Flow will assume the label is not a potential nonlocal goto 
+     destination in this case.  */
   unsigned frame_related : 1;
   /* The first element of the operands of this rtx.
      The number of operands and their types are controlled
diff -u --recursive --new-file clean/egcs-1.1.1/libiberty/config.table egcs-1.1.1/libiberty/config.table


More information about the Gcc-patches mailing list