From 30e9913fe6eb2f1c2519cfeacdf9100ccb26cbb7 Mon Sep 17 00:00:00 2001
From: mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 11 Aug 2004 02:50:14 +0000
Subject: [PATCH] 	* configure.in (arm*-*-eabi*): New target. 	*
 configure: Regenerate.

	* configure.ac (arm*-*-eabi*): New target.
	(arm*-*-symbianelf*): Likewise.
	* configure: Regenerated.

	* config.gcc (arm*-*-eabi*): New target.
	* defaults.h (TARGET_LIBGCC_FUNCS): New macro.
	(TARGET_LIB_INT_CMP_BIASED): Likewise.
	* expmed.c (expand_divmod): Try a two-valued divmod function as a
	last resort.
	* gthr.h: Remove bogus tokens at end of #pragma.
	* optabs.c (expand_twoval_binop_libfunc): New function.
	(prepare_cmp_insn): Handle the !TARGET_LIB_INT_CMP_BIASED case.
	(prepare_float_lib_cmp): Try reversing the condition.
	(debug_optab_libfuncs): New function.
	* optabs.h (expand_twoval_binop_libfunc): Declare.
	* config/arm/arm.c (arm_init_libfuncs): New function.
	(arm_compute_initial_eliminatino_offset): Return HOST_WIDE_INT.
	(TARGET_INIT_LIBFUNCS): Define it.
	* config/arm/arm.h (TARGET_BPABI): New macro.
	* config/arm/arm-protos.h
	(arm_compute_initial_elimination_offset): Return HOST_WIDE_INT.
	* config/arm/bpabi.S: New file.
	* config/arm/bpabi.c: Likewise.
	* config/arm/bpabi.h: Likewise.
	* config/arm/ieee754-df.S (__aeabi_dneg): New function or alias.
	(__aeabi_drsub): Likewise.
	(__aeabi_dsub): Likewise.
	(__aeabi_dadd): Likewise.
	(__aeabi_ui2d): Likewise.
	(__aeabi_i2d): Likewise.
	(__aeabi_f2d): Likewise.
	(__aeabi_dmul): Likewise.
	(__aeabi_ddiv): Likewise.
	(__aeabi_cdrcmple): Likewise.
	(__aeabi_cdcmpeq): Likewise.
	(__aeabi_cdcmple): Likewise.
	(__aeabi_dcmpeq): Likewise.
	(__aeabi_dcmplt): Likewise.
	(__aeabi_dcmple): Likewise.
	(__aeabi_dcmpge): Likewise.
	(__aeabi_dcmpgt): Likewise.
	(__aeabi_dcmpun): Likewise.
	(__aeabi_d2iz): Likewise.
	(__aeabi_d2uiz): Likewise.
	(__aeabi_d2f): Likewise.
	* config/arm/ieee754-sf.S (__aeabi_fneg): New function or alias.
	(__aeabi_frsub): Likewise.
	(__aeabi_fsub): Likewise.
	(__aeabi_fadd): Likewise.
	(__aeabi_ui2f): Likewise.
	(__aeabi_i2f): Likewise.
	(__aeabi_fmul): Likewise.
	(__aeabi_fdiv): Likewise.
	(__aeabi_cfrcmple): Likewise.
	(__aeabi_cfcmpeq): Likewise.
	(__aeabi_cfcmple): Likewise.
	(__aeabi_fcmpeq): Likewise.
	(__aeabi_fcmplt): Likewise.
	(__aeabi_fcmple): Likewise.
	(__aeabi_fcmpge): Likewise.
	(__aeabi_fcmpgt): Likewise.
	(__aeabi_fcmpun): Likewise.
	(__aeabi_f2iz): Likewise.
	(__aeabi_f2uiz): Likewise.
	* config/arm/lib1funcs.asm (ARM_CALL): New macro.
	(__aeabi_uidivmod): New function or alias.
	(__aeabi_idivmod): Likewise.
	(__aeabi_idiv0): Likewise.
	(__aeabi_ldiv0): Likewise.
	(__aeabi_llsr): Likewise.
	(__aeabi_lasr): Likewise.
	(__aeabi_llsl): Likewise.
	(bpabi.S): Include it.
	* config/arm/libgcc-bpabi.ver: New file.
	* config/arm/symbian.h (ARM_DEFAULT_ABI): Remove.
	(LINK_SPEC): Remove.
	* config/arm/t-arm-elf (LIB1ASMFUNCS): Add __aeabi_lcmp and
	__aeabi_ulcmp.
	* config/arm/t-bpabi: New file.
	* doc/tm.texi (TARGET_LIBGCC_FUNCS): New entry.
	(TARGET_LIB_INT_CMP_BIASED): Likewise.

	* gcc.dg/testsuite/gcc.dg/arm-eabi1.c: New test.
	* gcc.dg/dll-2.c: Fix dg-require syntax.
	* gcc.misc-tests/arm-isr.c (abort): Declare.
	(exit): Likewise.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85788 138bc75d-0d04-0410-961f-82ee72b054a4
---
 ChangeLog                              |   5 +
 configure                              |   2 +-
 configure.in                           |   2 +-
 gcc/ChangeLog                          |  80 +++++++
 gcc/config.gcc                         |  16 +-
 gcc/config/arm/arm-protos.h            |   4 +-
 gcc/config/arm/arm.c                   | 104 +++++++++-
 gcc/config/arm/arm.h                   |   8 +
 gcc/config/arm/bpabi.S                 |  95 +++++++++
 gcc/config/arm/bpabi.c                 |  94 +++++++++
 gcc/config/arm/bpabi.h                 |  83 ++++++++
 gcc/config/arm/ieee754-df.S            | 101 ++++++++-
 gcc/config/arm/ieee754-sf.S            | 150 +++++++++++++-
 gcc/config/arm/lib1funcs.asm           |  40 +++-
 gcc/config/arm/libgcc-bpabi.ver        |  63 ++++++
 gcc/config/arm/symbian.h               |   9 -
 gcc/config/arm/t-bpabi                 |   9 +
 gcc/defaults.h                         |  13 ++
 gcc/doc/tm.texi                        |  18 ++
 gcc/expmed.c                           |  22 +-
 gcc/gthr.h                             |   2 +-
 gcc/optabs.c                           | 276 ++++++++++++++++++-------
 gcc/optabs.h                           |   5 +
 gcc/testsuite/ChangeLog                |   7 +
 gcc/testsuite/gcc.dg/arm-eabi1.c       | 235 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/dll-2.c           |   2 +-
 gcc/testsuite/gcc.misc-tests/arm-isr.c |   3 +
 libcpp/ChangeLog                       |   6 +
 libcpp/configure                       | 165 ++++++++++-----
 libcpp/configure.ac                    |   2 +
 30 files changed, 1452 insertions(+), 169 deletions(-)
 create mode 100644 gcc/config/arm/bpabi.S
 create mode 100644 gcc/config/arm/bpabi.c
 create mode 100644 gcc/config/arm/bpabi.h
 create mode 100644 gcc/config/arm/libgcc-bpabi.ver
 create mode 100644 gcc/config/arm/t-bpabi
 create mode 100644 gcc/testsuite/gcc.dg/arm-eabi1.c

diff --git a/ChangeLog b/ChangeLog
index 26c0b8c8a45c..0f01bff895c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2004-08-09  Mark Mitchell  <mark@codesourcery.com>
+
+	* configure.in (arm*-*-eabi*): New target.
+	* configure: Regenerate.
+
 2004-08-06  Paolo Bonzini  <bonzini@gnu.org>
 
 	* Makefile.def (bfd, opcodes, gcc, zlib): Mark as bootstrap module.
diff --git a/configure b/configure
index 42faaf5e8eb4..53857ee0cdc3 100755
--- a/configure
+++ b/configure
@@ -1263,7 +1263,7 @@ case "${target}" in
   arm-*-coff | strongarm-*-coff | xscale-*-coff)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
-  arm-*-elf* | strongarm-*-elf* | xscale-*-elf*)
+  arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* )
     noconfigdirs="$noconfigdirs target-libffi target-qthreads"
     ;;
   arm*-*-symbianelf*)
diff --git a/configure.in b/configure.in
index e0be0344127b..9a04dad18900 100644
--- a/configure.in
+++ b/configure.in
@@ -479,7 +479,7 @@ case "${target}" in
   arm-*-coff | strongarm-*-coff | xscale-*-coff)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
-  arm-*-elf* | strongarm-*-elf* | xscale-*-elf*)
+  arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* )
     noconfigdirs="$noconfigdirs target-libffi target-qthreads"
     ;;
   arm*-*-symbianelf*)
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7a793511fd18..1022abd673e7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,83 @@
+2004-08-09  Mark Mitchell  <mark@codesourcery.com>
+
+	* config.gcc (arm*-*-eabi*): New target.
+	* defaults.h (TARGET_LIBGCC_FUNCS): New macro.
+	(TARGET_LIB_INT_CMP_BIASED): Likewise.
+	* expmed.c (expand_divmod): Try a two-valued divmod function as a
+	last resort.
+	* gthr.h: Remove bogus tokens at end of #pragma.
+	* optabs.c (expand_twoval_binop_libfunc): New function.
+	(prepare_cmp_insn): Handle the !TARGET_LIB_INT_CMP_BIASED case.
+	(prepare_float_lib_cmp): Try reversing the condition.
+	(debug_optab_libfuncs): New function.
+	* optabs.h (expand_twoval_binop_libfunc): Declare.
+	* config/arm/arm.c (arm_init_libfuncs): New function.
+	(arm_compute_initial_eliminatino_offset): Return HOST_WIDE_INT.
+	(TARGET_INIT_LIBFUNCS): Define it.
+	* config/arm/arm.h (TARGET_BPABI): New macro.
+	* config/arm/arm-protos.h
+	(arm_compute_initial_elimination_offset): Return HOST_WIDE_INT.
+	* config/arm/bpabi.S: New file.
+	* config/arm/bpabi.c: Likewise.
+	* config/arm/bpabi.h: Likewise.
+	* config/arm/ieee754-df.S (__aeabi_dneg): New function or alias.
+	(__aeabi_drsub): Likewise.
+	(__aeabi_dsub): Likewise.
+	(__aeabi_dadd): Likewise.
+	(__aeabi_ui2d): Likewise.
+	(__aeabi_i2d): Likewise.
+	(__aeabi_f2d): Likewise.
+	(__aeabi_dmul): Likewise.
+	(__aeabi_ddiv): Likewise.
+	(__aeabi_cdrcmple): Likewise.
+	(__aeabi_cdcmpeq): Likewise.
+	(__aeabi_cdcmple): Likewise.
+	(__aeabi_dcmpeq): Likewise.
+	(__aeabi_dcmplt): Likewise.
+	(__aeabi_dcmple): Likewise.
+	(__aeabi_dcmpge): Likewise.
+	(__aeabi_dcmpgt): Likewise.
+	(__aeabi_dcmpun): Likewise.
+	(__aeabi_d2iz): Likewise.
+	(__aeabi_d2uiz): Likewise.
+	(__aeabi_d2f): Likewise.
+	* config/arm/ieee754-sf.S (__aeabi_fneg): New function or alias.
+	(__aeabi_frsub): Likewise.
+	(__aeabi_fsub): Likewise.
+	(__aeabi_fadd): Likewise.
+	(__aeabi_ui2f): Likewise.
+	(__aeabi_i2f): Likewise.
+	(__aeabi_fmul): Likewise.
+	(__aeabi_fdiv): Likewise.
+	(__aeabi_cfrcmple): Likewise.
+	(__aeabi_cfcmpeq): Likewise.
+	(__aeabi_cfcmple): Likewise.
+	(__aeabi_fcmpeq): Likewise.
+	(__aeabi_fcmplt): Likewise.
+	(__aeabi_fcmple): Likewise.
+	(__aeabi_fcmpge): Likewise.
+	(__aeabi_fcmpgt): Likewise.
+	(__aeabi_fcmpun): Likewise.
+	(__aeabi_f2iz): Likewise.
+	(__aeabi_f2uiz): Likewise.
+	* config/arm/lib1funcs.asm (ARM_CALL): New macro.
+	(__aeabi_uidivmod): New function or alias.
+	(__aeabi_idivmod): Likewise.
+	(__aeabi_idiv0): Likewise.
+	(__aeabi_ldiv0): Likewise.
+	(__aeabi_llsr): Likewise.
+	(__aeabi_lasr): Likewise.
+	(__aeabi_llsl): Likewise.
+	(bpabi.S): Include it.
+	* config/arm/libgcc-bpabi.ver: New file.
+	* config/arm/symbian.h (ARM_DEFAULT_ABI): Remove.
+	(LINK_SPEC): Remove.
+	* config/arm/t-arm-elf (LIB1ASMFUNCS): Add __aeabi_lcmp and
+	__aeabi_ulcmp.
+	* config/arm/t-bpabi: New file.
+	* doc/tm.texi (TARGET_LIBGCC_FUNCS): New entry.
+	(TARGET_LIB_INT_CMP_BIASED): Likewise.
+	
 2004-08-10  David Edelsohn  <edelsohn@gnu.org>
 
 	* config/rs6000/rs6000-protos.h (expand_block_clear): Declare.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 68d80826f2dc..d6e95c700579 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -652,9 +652,19 @@ arm*-*-ecos-elf)
 	tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/ecos-elf.h"
 	tmake_file="arm/t-arm arm/t-arm-elf"
 	;;
-arm*-*-symbianelf*)
-	tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/symbian.h arm/aout.h arm/arm.h"
-	tmake_file="t-slibgcc-elf-ver arm/t-arm arm/t-arm-elf"
+arm*-*-eabi* | arm*-*-symbianelf* )
+	# The BPABI long long divmod functions return a 128-bit value in 
+	# registers r0-r3.  Correctly modeling that requires the use of
+	# TImode.
+	need_64bit_hwint=yes
+	tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/bpabi.h"
+	case ${target} in
+	arm*-*-symbianelf*)
+	  tm_file="${tm_file} arm/symbian.h"
+	  ;;
+	esac
+	tm_file="${tm_file} arm/aout.h arm/arm.h"
+	tmake_file="t-slibgcc-elf-ver arm/t-arm arm/t-arm-elf arm/t-bpabi"
 	;;
 arm*-*-rtems*)
 	tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/rtems-elf.h rtems.h"
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index e2224557dc19..2f361cd63627 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -34,8 +34,8 @@ extern void arm_expand_prologue (void);
 extern const char *arm_strip_name_encoding (const char *);
 extern void arm_asm_output_labelref (FILE *, const char *);
 extern unsigned long arm_current_func_type (void);
-extern unsigned int arm_compute_initial_elimination_offset (unsigned int,
-							    unsigned int);
+extern HOST_WIDE_INT arm_compute_initial_elimination_offset (unsigned int,
+							     unsigned int);
 extern HOST_WIDE_INT thumb_compute_initial_elimination_offset (unsigned int,
 							       unsigned int);
 
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 240d96c67a42..40b2fd45c652 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -169,6 +169,7 @@ static bool arm_cxx_guard_mask_bit (void);
 static tree arm_get_cookie_size (tree);
 static bool arm_cookie_has_size (void);
 static bool arm_cxx_cdtor_returns_this (void);
+static void arm_init_libfuncs (void);
 
 
 /* Initialize the GCC target structure.  */
@@ -250,6 +251,9 @@ static bool arm_cxx_cdtor_returns_this (void);
 #undef  TARGET_EXPAND_BUILTIN
 #define TARGET_EXPAND_BUILTIN arm_expand_builtin
 
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS arm_init_libfuncs
+
 #undef TARGET_PROMOTE_FUNCTION_ARGS
 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
 #undef TARGET_PROMOTE_FUNCTION_RETURN
@@ -614,6 +618,104 @@ bit_count (unsigned long value)
   return count;
 }
 
+/* Set up library functions uqniue to ARM.  */
+
+static void
+arm_init_libfuncs (void)
+{
+  /* There are no special library functions unless we are using the
+     ARM BPABI.  */
+  if (!TARGET_BPABI)
+    return;
+
+  /* The functions below are described in Section 4 of the "Run-Time
+     ABI for the ARM architecture", Version 1.0.  */
+
+  /* Double-precision floating-point arithmetic.  Table 2.  */
+  set_optab_libfunc (add_optab, DFmode, "__aeabi_dadd");
+  set_optab_libfunc (sdiv_optab, DFmode, "__aeabi_ddiv");
+  set_optab_libfunc (smul_optab, DFmode, "__aeabi_dmul");
+  set_optab_libfunc (neg_optab, DFmode, "__aeabi_dneg");
+  set_optab_libfunc (sub_optab, DFmode, "__aeabi_dsub");
+
+  /* Double-precision comparisions.  Table 3.  */
+  set_optab_libfunc (eq_optab, DFmode, "__aeabi_dcmpeq");
+  set_optab_libfunc (ne_optab, DFmode, NULL);
+  set_optab_libfunc (lt_optab, DFmode, "__aeabi_dcmplt");
+  set_optab_libfunc (le_optab, DFmode, "__aeabi_dcmple");
+  set_optab_libfunc (ge_optab, DFmode, "__aeabi_dcmpge");
+  set_optab_libfunc (gt_optab, DFmode, "__aeabi_dcmpgt");
+  set_optab_libfunc (unord_optab, DFmode, "__aeabi_dcmpun");
+
+  /* Single-precision floating-point arithmetic.  Table 4.  */
+  set_optab_libfunc (add_optab, SFmode, "__aeabi_fadd");
+  set_optab_libfunc (sdiv_optab, SFmode, "__aeabi_fdiv");
+  set_optab_libfunc (smul_optab, SFmode, "__aeabi_fmul");
+  set_optab_libfunc (neg_optab, SFmode, "__aeabi_fneg");
+  set_optab_libfunc (sub_optab, SFmode, "__aeabi_fsub");
+  
+  /* Single-precision comparisions.  Table 5.  */
+  set_optab_libfunc (eq_optab, SFmode, "__aeabi_fcmpeq");
+  set_optab_libfunc (ne_optab, SFmode, NULL);
+  set_optab_libfunc (lt_optab, SFmode, "__aeabi_fcmplt");
+  set_optab_libfunc (le_optab, SFmode, "__aeabi_fcmple");
+  set_optab_libfunc (ge_optab, SFmode, "__aeabi_fcmpge");
+  set_optab_libfunc (gt_optab, SFmode, "__aeabi_fcmpgt");
+  set_optab_libfunc (unord_optab, SFmode, "__aeabi_fcmpun");
+
+  /* Floating-point to integer conversions.  Table 6.  */
+  set_conv_libfunc (sfix_optab, SImode, DFmode, "__aeabi_d2iz");
+  set_conv_libfunc (ufix_optab, SImode, DFmode, "__aeabi_d2uiz");
+  set_conv_libfunc (sfix_optab, DImode, DFmode, "__aeabi_d2lz");
+  set_conv_libfunc (ufix_optab, DImode, DFmode, "__aeabi_d2ulz");
+  set_conv_libfunc (sfix_optab, SImode, SFmode, "__aeabi_f2iz");
+  set_conv_libfunc (ufix_optab, SImode, SFmode, "__aeabi_f2uiz");
+  set_conv_libfunc (sfix_optab, DImode, SFmode, "__aeabi_f2lz");
+  set_conv_libfunc (ufix_optab, DImode, SFmode, "__aeabi_f2ulz");
+
+  /* Conversions between floating types.  Table 7.  */
+  set_conv_libfunc (trunc_optab, SFmode, DFmode, "__aeabi_d2f");
+  set_conv_libfunc (sext_optab, DFmode, SFmode, "__aeabi_f2d");
+
+  /* Integer to floating-point converisons.  Table 8.  */
+  set_conv_libfunc (sfloat_optab, DFmode, SImode, "__aeabi_i2d");
+  set_conv_libfunc (ufloat_optab, DFmode, SImode, "__aeabi_ui2d");
+  set_conv_libfunc (sfloat_optab, DFmode, DImode, "__aeabi_l2d");
+  set_conv_libfunc (ufloat_optab, DFmode, DImode, "__aeabi_ul2d");
+  set_conv_libfunc (sfloat_optab, SFmode, SImode, "__aeabi_i2f");
+  set_conv_libfunc (ufloat_optab, SFmode, SImode, "__aeabi_ui2f");
+  set_conv_libfunc (sfloat_optab, SFmode, DImode, "__aeabi_l2f");
+  set_conv_libfunc (ufloat_optab, SFmode, DImode, "__aeabi_ul2f");
+
+  /* Long long.  Table 9.  */
+  set_optab_libfunc (smul_optab, DImode, "__aeabi_lmul");
+  set_optab_libfunc (sdivmod_optab, DImode, "__aeabi_ldivmod");
+  set_optab_libfunc (udivmod_optab, DImode, "__aeabi_uldivmod");
+  set_optab_libfunc (ashl_optab, DImode, "__aeabi_llsl");
+  set_optab_libfunc (lshr_optab, DImode, "__aeabi_llsr");
+  set_optab_libfunc (ashr_optab, DImode, "__aeabi_lasr");
+  set_optab_libfunc (cmp_optab, DImode, "__aeabi_lcmp");
+  set_optab_libfunc (ucmp_optab, DImode, "__aeabi_ulcmp");
+
+  /* Integer (32/32->32) division.  \S 4.3.1.  */
+  set_optab_libfunc (sdivmod_optab, SImode, "__aeabi_idivmod");
+  set_optab_libfunc (udivmod_optab, SImode, "__aeabi_uidivmod");
+
+  /* The divmod functions are designed so that they can be used for
+     plain division, even though they return both the quotient and the
+     remainder.  The quotient is returned in the usual location (i.e.,
+     r0 for SImode, {r0, r1} for DImode), just as would be expected
+     for an ordinary division routine.  Because the AAPCS calling
+     conventions specify that all of { r0, r1, r2, r3 } are
+     callee-saved registers, there is no need to tell the compiler
+     explicitly that those registers are clobbered by these
+     routines.  */
+  set_optab_libfunc (sdiv_optab, DImode, "__aeabi_ldivmod");
+  set_optab_libfunc (udiv_optab, DImode, "__aeabi_uldivmod");
+  set_optab_libfunc (sdiv_optab, SImode, "__aeabi_idivmod");
+  set_optab_libfunc (udiv_optab, SImode, "__aeabi_uidivmod");
+}
+
 /* Fix up any incompatible options that the user has specified.
    This has now turned into a maze.  */
 void
@@ -10165,7 +10267,7 @@ arm_get_frame_offsets (void)
 /* Calculate the relative offsets for the different stack pointers.  Positive
    offsets are in the direction of stack growth.  */
 
-unsigned int
+HOST_WIDE_INT
 arm_compute_initial_elimination_offset (unsigned int from, unsigned int to)
 {
   arm_stack_offsets *offsets;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 5dfd4a0596dc..c3e82235c168 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -296,6 +296,14 @@ extern GTY(()) rtx aof_pic_label;
 #define TARGET_AAPCS_BASED \
     (arm_abi != ARM_ABI_APCS && arm_abi != ARM_ABI_ATPCS)
 
+/* True iff the full BPABI is being used.  If TARGET_BPABI is true,
+   then TARGET_AAPCS_BASED must be true -- but the converse does not
+   hold.  TARGET_BPABI implies the use of the BPABI runtime library,
+   etc., in addition to just the AAPCS calling conventions.  */
+#ifndef TARGET_BPABI
+#define TARGET_BPABI false
+#endif 
+
 /* SUBTARGET_SWITCHES is used to add flags on a per-config basis.  */
 #ifndef SUBTARGET_SWITCHES
 #define SUBTARGET_SWITCHES
diff --git a/gcc/config/arm/bpabi.S b/gcc/config/arm/bpabi.S
new file mode 100644
index 000000000000..bebbce5f3e52
--- /dev/null
+++ b/gcc/config/arm/bpabi.S
@@ -0,0 +1,95 @@
+/* Miscellaneous BPABI functions.
+
+   Copyright (C) 2003, 2004  Free Software Foundation, Inc.
+   Contributed by CodeSourcery, LLC.
+
+   This file 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.
+
+   In addition to the permissions in the GNU General Public License, the
+   Free Software Foundation gives you unlimited permission to link the
+   compiled version of this file into combinations with other programs,
+   and to distribute those combinations without any restriction coming
+   from the use of this file.  (The General Public License restrictions
+   do apply in other respects; for example, they cover modification of
+   the file, and distribution when not linked into a combine
+   executable.)
+
+   This file 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.  */
+
+#ifdef __ARMEB__
+#define xxh r0
+#define xxl r1
+#define yyh r2
+#define yyl r3
+#else
+#define xxh r1
+#define xxl r0
+#define yyh r3
+#define yyl r2
+#endif	
+	
+#ifdef L_aeabi_lcmp
+
+ARM_FUNC_START aeabi_lcmp
+	subs	ip, xxl, yyl
+	sbcs	ip, xxh, yyh
+	subeqs  ip, xxl, yyl
+	mov	r0, ip
+	RET
+	FUNC_END aeabi_lcmp
+
+#endif /* L_aeabi_lcmp */
+	
+#ifdef L_aeabi_ulcmp
+
+ARM_FUNC_START aeabi_ulcmp
+	cmp	xxh, yyh
+	movlo	r0, #-1
+	movhi	r0, #1
+	RETc(ne)
+	cmp	xxl, yyl
+	movlo	r0, #-1
+	movhi	r0, #1
+	moveq	r0, #0
+	RET
+	FUNC_END aeabi_ulcmp
+
+#endif /* L_aeabi_ulcmp */
+
+#ifdef L_aeabi_ldivmod
+
+ARM_FUNC_START aeabi_ldivmod
+	sub sp, sp, #8
+	stmfd sp!, {sp, lr}
+	bl SYM(__gnu_ldivmod_helper) __PLT__
+	ldr lr, [sp, #4]
+	add sp, sp, #8
+	ldmfd sp!, {r2, r3}
+	RET
+	
+#endif /* L_aeabi_ldivmod */
+
+#ifdef L_aeabi_uldivmod
+
+ARM_FUNC_START aeabi_uldivmod
+	sub sp, sp, #8
+	stmfd sp!, {sp, lr}
+	bl SYM(__gnu_uldivmod_helper) __PLT__
+	ldr lr, [sp, #4]
+	add sp, sp, #8
+	ldmfd sp!, {r2, r3}
+	RET
+	
+#endif /* L_aeabi_divmod */
+	
diff --git a/gcc/config/arm/bpabi.c b/gcc/config/arm/bpabi.c
new file mode 100644
index 000000000000..7bdc161215c2
--- /dev/null
+++ b/gcc/config/arm/bpabi.c
@@ -0,0 +1,94 @@
+/* Miscellaneous BPABI functions.
+
+   Copyright (C) 2003, 2004  Free Software Foundation, Inc.
+   Contributed by CodeSourcery, LLC.
+
+   This file 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.
+
+   In addition to the permissions in the GNU General Public License, the
+   Free Software Foundation gives you unlimited permission to link the
+   compiled version of this file into combinations with other programs,
+   and to distribute those combinations without any restriction coming
+   from the use of this file.  (The General Public License restrictions
+   do apply in other respects; for example, they cover modification of
+   the file, and distribution when not linked into a combine
+   executable.)
+
+   This file 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.  */
+
+extern double __aeabi_ul2d (unsigned long long);
+extern float __aeabi_ul2f (unsigned long long);
+extern long long __divdi3 (long long, long long);
+extern unsigned long long __udivdi3 (unsigned long long, 
+				     unsigned long long);
+extern long long __gnu_ldivmod_helper (long long, long long, long long *);
+extern unsigned long long __gnu_uldivmod_helper (unsigned long long, 
+						 unsigned long long, 
+						 unsigned long long *);
+
+/* These functions are based on __floatdidf and __floatdisf, but
+   convert unsigned DImode values instead of signed DImode
+   values.  */
+
+#define WORD_SIZE (sizeof (int) * 8)
+#define HIGH_HALFWORD_COEFF (((unsigned long long) 1) << (WORD_SIZE / 2))
+#define HIGH_WORD_COEFF (((unsigned long long) 1) << WORD_SIZE)
+
+double
+__aeabi_ul2d (unsigned long long u)
+{
+  double d = (unsigned) (u >> WORD_SIZE);
+  d *= HIGH_HALFWORD_COEFF;
+  d *= HIGH_HALFWORD_COEFF;
+  d += (unsigned) (u & (HIGH_WORD_COEFF - 1));
+
+  return d;
+}
+
+float
+__aeabi_ul2f (unsigned long long u)
+{
+  /* Do the calculation in DFmode so that we don't lose any of the
+     precision of the high word while multiplying it.  */
+  double f = (unsigned) (u >> WORD_SIZE);
+  f *= HIGH_HALFWORD_COEFF;
+  f *= HIGH_HALFWORD_COEFF;
+  f += (unsigned) (u & (HIGH_WORD_COEFF - 1));
+
+  return (float) f;
+}
+
+long long
+__gnu_ldivmod_helper (long long a, 
+		      long long b, 
+		      long long *remainder)
+{
+  long long quotient;
+
+  quotient = __divdi3 (a, b);
+  *remainder = a - b * quotient;
+  return quotient;
+}
+
+unsigned long long
+__gnu_uldivmod_helper (unsigned long long a, 
+		       unsigned long long b,
+		       unsigned long long *remainder)
+{
+  unsigned long long quotient;
+
+  quotient = __udivdi3 (a, b);
+  *remainder = a - b * quotient;
+  return quotient;
+}
diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h
new file mode 100644
index 000000000000..7647608c7acc
--- /dev/null
+++ b/gcc/config/arm/bpabi.h
@@ -0,0 +1,83 @@
+/* Configuration file for ARM BPABI targets.
+   Copyright (C) 2004
+   Free Software Foundation, Inc.
+   Contributed by CodeSourcery, LLC   
+
+   This file is part of GCC.
+
+   GCC 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.
+
+   GCC 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 GCC; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Use the AAPCS ABI by default.  */
+#define ARM_DEFAULT_ABI ARM_ABI_AAPCS
+
+/* Assume that AAPCS ABIs should adhere to the full BPABI.  */ 
+#define TARGET_BPABI (TARGET_AAPCS_BASED)
+
+/* The ARM BPABI functions return a boolean; they use no special
+   calling convention.  */
+#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) TARGET_BPABI
+
+/* Do not generate calls to any of the standard GCC functions in
+   libgcc when generating BPABI code.  */
+#define TARGET_LIBGCC_LIBFUNCS !TARGET_BPABI
+
+/* The BPABI integer comparision routines return { -1, 0, 1 }.  */
+#define TARGET_LIB_INT_CMP_BIASED !TARGET_BPABI
+
+/* The generic link spec in elf.h does not support shared libraries.  */
+#undef LINK_SPEC
+#define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} "		\
+  "%{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} "	\
+  "-X"
+
+#if defined (__thumb__) && !defined (__THUMB_INTERWORD) 
+#define RENAME_LIBRARY_SET ".thumb_set"
+#else
+#define RENAME_LIBRARY_SET ".set"
+#endif
+
+/* Make __aeabi_AEABI_NAME an alias for __GCC_NAME.  */
+#define RENAME_LIBRARY(GCC_NAME, AEABI_NAME)		\
+  __asm__ (".globl\t__aeabi_" #AEABI_NAME "\n"		\
+	   RENAME_LIBRARY_SET "\t__aeabi_" #AEABI_NAME 	\
+	     ", __" #GCC_NAME "\n");
+
+/* Give some libgcc functions an additional __aeabi name.  */
+#ifdef L_muldi3
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, lmul)
+#endif
+#ifdef L_muldi3
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, lmul)
+#endif
+#ifdef L_fixdfdi
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixdfdi, d2lz)
+#endif
+#ifdef L_fixunsdfdi
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfdi, d2ulz)
+#endif
+#ifdef L_fixsfdi
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f2lz)
+#endif
+#ifdef L_fixunssfdi
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f2ulz)
+#endif
+#ifdef L_floatdidf
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdidf, l2d)
+#endif
+#ifdef L_floatdisf
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdisf, l2f)
+#endif
+
diff --git a/gcc/config/arm/ieee754-df.S b/gcc/config/arm/ieee754-df.S
index 6a7aab859385..11b356a4186c 100644
--- a/gcc/config/arm/ieee754-df.S
+++ b/gcc/config/arm/ieee754-df.S
@@ -59,17 +59,25 @@
 #ifdef L_negdf2
 
 ARM_FUNC_START negdf2
+ARM_FUNC_ALIAS aeabi_dneg negdf2
 	@ flip sign bit
 	eor	xh, xh, #0x80000000
 	RET
 
+	FUNC_END aeabi_dneg
 	FUNC_END negdf2
 
 #endif
 
 #ifdef L_addsubdf3
 
-ARM_FUNC_START subdf3
+ARM_FUNC_START aeabi_drsub
+
+	eor	xh, xh, #0x80000000	@ flip sign bit of first arg
+	b	1f	
+
+	ARM_FUNC_START subdf3
+ARM_FUNC_ALIAS aeabi_dsub subdf3
 	@ flip sign bit of second arg
 	eor	yh, yh, #0x80000000
 #if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
@@ -77,6 +85,7 @@ ARM_FUNC_START subdf3
 #endif
 
 ARM_FUNC_START adddf3
+ARM_FUNC_ALIAS aeabi_dadd adddf3
 
 1:	@ Compare both args, return zero if equal but the sign.
 	teq	xl, yl
@@ -373,10 +382,13 @@ LSYM(Lad_i):
 	movne	xl, #0
 	RETLDM	"r4, r5"
 
+	FUNC_END aeabi_dsub
 	FUNC_END subdf3
+	FUNC_END aeabi_dadd
 	FUNC_END adddf3
 
 ARM_FUNC_START floatunsidf
+ARM_FUNC_ALIAS aeabi_ui2d floatunsidf
 	teq	r0, #0
 	moveq	r1, #0
 	RETc(eq)
@@ -388,9 +400,11 @@ ARM_FUNC_START floatunsidf
 	mov	xh, #0
 	b	LSYM(Lad_l)
 
+	FUNC_END aeabi_ui2d
 	FUNC_END floatunsidf
 
 ARM_FUNC_START floatsidf
+ARM_FUNC_ALIAS aeabi_i2d floatsidf
 	teq	r0, #0
 	moveq	r1, #0
 	RETc(eq)
@@ -403,9 +417,12 @@ ARM_FUNC_START floatsidf
 	mov	xh, #0
 	b	LSYM(Lad_l)
 
+	FUNC_END aeabi_i2d
 	FUNC_END floatsidf
 
 ARM_FUNC_START extendsfdf2
+ARM_FUNC_ALIAS aeabi_f2d extendsfdf2
+	
 	movs	r2, r0, lsl #1
 	beq	1f			@ value is 0.0 or -0.0
 	mov	xh, r2, asr #3		@ stretch exponent
@@ -429,6 +446,7 @@ ARM_FUNC_START extendsfdf2
 	bic	xh, xh, #0x80000000
 	b	LSYM(Lad_l)
 
+	FUNC_END aeabi_f2d
 	FUNC_END extendsfdf2
 
 #endif /* L_addsubdf3 */
@@ -436,7 +454,7 @@ ARM_FUNC_START extendsfdf2
 #ifdef L_muldivdf3
 
 ARM_FUNC_START muldf3
-
+ARM_FUNC_ALIAS aeabi_dmul muldf3
 	stmfd	sp!, {r4, r5, r6, lr}
 
 	@ Mask out exponents.
@@ -722,10 +740,12 @@ LSYM(Lml_n):
 	orr	xh, xh, #0x00f80000
 	RETLDM	"r4, r5, r6"
 
+	FUNC_END aeabi_dmul
 	FUNC_END muldf3
 
 ARM_FUNC_START divdf3
-
+ARM_FUNC_ALIAS aeabi_ddiv divdf3
+	
 	stmfd	sp!, {r4, r5, r6, lr}
 
 	@ Mask out exponents.
@@ -934,6 +954,7 @@ LSYM(Ldv_s):
 	bne	LSYM(Lml_z)		@ 0 / <non_zero> -> 0
 	b	LSYM(Lml_n)		@ 0 / 0 -> NAN
 
+	FUNC_END aeabi_ddiv
 	FUNC_END divdf3
 
 #endif /* L_muldivdf3 */
@@ -1013,11 +1034,78 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
 	FUNC_END eqdf2
 	FUNC_END cmpdf2
 
+ARM_FUNC_START aeabi_cdrcmple
+	mov	ip, r0
+	mov	r0, r2
+	mov	r2, ip
+	mov	ip, r1
+	mov	r1, r3
+	mov	r3, ip
+	b	6f
+	
+ARM_FUNC_START aeabi_cdcmpeq
+ARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq
+	@ The status-returning routines are required to preserve all
+	@ registers except ip, lr, and cpsr.
+6:	stmfd	sp!, {r0, r1, r2, r3, lr}
+	ARM_CALL cmpdf2
+	@ Set the Z flag correctly, and the C flag unconditionally.
+	cmp	 r0, #0
+	@ Clear the C flag if the return value was -1, indicating
+	@ that the first operand was smaller than the second.
+	cmnmi	 r0, #0
+	RETLDM   "r0, r1, r2, r3"
+	FUNC_END aeabi_cdcmple
+	FUNC_END aeabi_cdcmpeq
+	
+ARM_FUNC_START	aeabi_dcmpeq
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cdcmple
+	moveq	r0, #1	@ Equal to.
+	movne	r0, #0	@ Less than, greater than, or unordered.
+	RETLDM
+	FUNC_END aeabi_dcmpeq
+
+ARM_FUNC_START	aeabi_dcmplt
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cdcmple
+	movcc	r0, #1	@ Less than.
+	movcs	r0, #0	@ Equal to, greater than, or unordered.
+	RETLDM
+	FUNC_END aeabi_dcmplt
+
+ARM_FUNC_START	aeabi_dcmple
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cdcmple
+	movls	r0, #1  @ Less than or equal to.
+	movhi	r0, #0	@ Greater than or unordered.
+	RETLDM
+	FUNC_END aeabi_dcmple
+
+ARM_FUNC_START	aeabi_dcmpge
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cdrcmple
+	movls	r0, #1	@ Operand 2 is less than or equal to operand 1.
+	movhi	r0, #0	@ Operand 2 greater than operand 1, or unordered.
+	RETLDM
+	FUNC_END aeabi_dcmpge
+
+ARM_FUNC_START	aeabi_dcmpgt
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cdrcmple
+	movcc	r0, #1	@ Operand 2 is less than operand 1.
+	movcs	r0, #0  @ Operand 2 is greater than or equal to operand 1,
+			@ or they are unordered.
+	RETLDM
+	FUNC_END aeabi_dcmpgt
+		
 #endif /* L_cmpdf2 */
 
 #ifdef L_unorddf2
 
 ARM_FUNC_START unorddf2
+ARM_FUNC_ALIAS aeabi_dcmpun unorddf2
+	
 	str	lr, [sp, #-4]!
 	mov	ip, #0x7f000000
 	orr	ip, ip, #0x00f00000
@@ -1037,6 +1125,7 @@ ARM_FUNC_START unorddf2
 3:	mov	r0, #1			@ arguments are unordered.
 	RETLDM
 
+	FUNC_END aeabi_dcmpun
 	FUNC_END unorddf2
 
 #endif /* L_unorddf2 */
@@ -1044,6 +1133,7 @@ ARM_FUNC_START unorddf2
 #ifdef L_fixdfsi
 
 ARM_FUNC_START fixdfsi
+ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
 	orrs	ip, xl, xh, lsl #1
 	beq	1f			@ value is 0.
 
@@ -1084,6 +1174,7 @@ ARM_FUNC_START fixdfsi
 4:	mov	r0, #0			@ How should we convert NAN?
 	RET
 
+	FUNC_END aeabi_d2iz
 	FUNC_END fixdfsi
 
 #endif /* L_fixdfsi */
@@ -1091,6 +1182,7 @@ ARM_FUNC_START fixdfsi
 #ifdef L_fixunsdfsi
 
 ARM_FUNC_START fixunsdfsi
+ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi
 	orrs	ip, xl, xh, lsl #1
 	movcss	r0, #0			@ value is negative
 	RETc(eq)			@ or 0 (xl, xh overlap r0)
@@ -1127,6 +1219,7 @@ ARM_FUNC_START fixunsdfsi
 4:	mov	r0, #0			@ How should we convert NAN?
 	RET
 
+	FUNC_END aeabi_d2uiz
 	FUNC_END fixunsdfsi
 
 #endif /* L_fixunsdfsi */
@@ -1134,6 +1227,7 @@ ARM_FUNC_START fixunsdfsi
 #ifdef L_truncdfsf2
 
 ARM_FUNC_START truncdfsf2
+ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
 	orrs	r2, xl, xh, lsl #1
 	moveq	r0, r2, rrx
 	RETc(eq)			@ value is 0.0 or -0.0
@@ -1219,6 +1313,7 @@ ARM_FUNC_START truncdfsf2
 	and	xh, xh, #0x80000000
 	b	5b
 
+	FUNC_END aeabi_d2f
 	FUNC_END truncdfsf2
 
 #endif /* L_truncdfsf2 */
diff --git a/gcc/config/arm/ieee754-sf.S b/gcc/config/arm/ieee754-sf.S
index 5c972452954b..627fd7231d34 100644
--- a/gcc/config/arm/ieee754-sf.S
+++ b/gcc/config/arm/ieee754-sf.S
@@ -41,23 +41,34 @@
 #ifdef L_negsf2
 	
 ARM_FUNC_START negsf2
+ARM_FUNC_ALIAS aeabi_fneg negsf2
+	
 	eor	r0, r0, #0x80000000	@ flip sign bit
 	RET
 
+	FUNC_END aeabi_fneg
 	FUNC_END negsf2
 
 #endif
 
 #ifdef L_addsubsf3
 
+ARM_FUNC_START aeabi_frsub
+
+	eor	r0, r0, #0x80000000	@ flip sign bit of first arg
+	b	1f	
+	
 ARM_FUNC_START subsf3
+ARM_FUNC_ALIAS aeabi_fsub subsf3
+	
 	eor	r1, r1, #0x80000000	@ flip sign bit of second arg
 #if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
 	b	1f			@ Skip Thumb-code prologue
 #endif
 
 ARM_FUNC_START addsf3
-
+ARM_FUNC_ALIAS aeabi_fadd addsf3
+	
 1:	@ Compare both args, return zero if equal but the sign.
 	eor	r2, r0, r1
 	teq	r2, #0x80000000
@@ -258,14 +269,21 @@ LSYM(Lad_i):
 	orrne	r0, r3, #0x00400000	@ NAN
 	RET
 
+	FUNC_END aeabi_frsub
+	FUNC_END aeabi_fadd
 	FUNC_END addsf3
+	FUNC_END aeabi_fsub
 	FUNC_END subsf3
 
 ARM_FUNC_START floatunsisf
+ARM_FUNC_ALIAS aeabi_ui2f floatunsisf
+		
 	mov	r3, #0
 	b	1f
 
 ARM_FUNC_START floatsisf
+ARM_FUNC_ALIAS aeabi_i2f floatsisf
+	
 	ands	r3, r0, #0x80000000
 	rsbmi	r0, r0, #0
 
@@ -290,7 +308,9 @@ ARM_FUNC_START floatsisf
 	add	r2, r2, #(2 << 23)
 	b	LSYM(Lad_p)
 
+	FUNC_END aeabi_i2f
 	FUNC_END floatsisf
+	FUNC_END aeabi_ui2f
 	FUNC_END floatunsisf
 
 #endif /* L_addsubsf3 */
@@ -298,7 +318,8 @@ ARM_FUNC_START floatsisf
 #ifdef L_muldivsf3
 
 ARM_FUNC_START mulsf3
-
+ARM_FUNC_ALIAS aeabi_fmul mulsf3
+	
 	@ Mask out exponents.
 	mov	ip, #0xff000000
 	and	r2, r0, ip, lsr #1
@@ -485,10 +506,12 @@ LSYM(Lml_n):
 	orr	r0, r0, #0x00c00000
 	RET
 
+	FUNC_END aeabi_fmul
 	FUNC_END mulsf3
 
 ARM_FUNC_START divsf3
-
+ARM_FUNC_ALIAS aeabi_fdiv divsf3
+	
 	@ Mask out exponents.
 	mov	ip, #0xff000000
 	and	r2, r0, ip, lsr #1
@@ -636,12 +659,28 @@ LSYM(Ldv_s):
 	bne	LSYM(Lml_z)		@ 0 / <non_zero> -> 0
 	b	LSYM(Lml_n)		@ 0 / 0 -> NAN
 
+	FUNC_END aeabi_fdiv
 	FUNC_END divsf3
 
 #endif /* L_muldivsf3 */
 
 #ifdef L_cmpsf2
 
+	@ The return value in r0 is
+	@
+	@   0  if the operands are equal
+	@   1  if the first operand is greater than the second, or
+	@      the operands are unordered and the operation is
+	@      CMP, LT, LE, NE, or EQ.
+	@   -1 if the first operand is less than the second, or
+	@      the operands are unordered and the operation is GT
+	@      or GE.
+	@
+	@ The Z flag will be set iff the operands are equal.
+	@
+	@ The following registers are clobbered by this function:
+	@   ip, r0, r1, r2, r3
+
 ARM_FUNC_START gtsf2
 ARM_FUNC_ALIAS gesf2 gtsf2
 	mov	r3, #-1
@@ -657,24 +696,31 @@ ARM_FUNC_ALIAS nesf2 cmpsf2
 ARM_FUNC_ALIAS eqsf2 cmpsf2
 	mov	r3, #1			@ how should we specify unordered here?
 
-1:	@ Trap any INF/NAN first.
-	mov	ip, #0xff000000
+	@ Both Inf and NaN have an exponent of 255.  Therefore, we
+	@ compute (r1 & 0x8f80000) || (r2 & 0x8f8000).
+1:	mov	ip, #0xff000000
 	and	r2, r1, ip, lsr #1
 	teq	r2, ip, lsr #1
 	and	r2, r0, ip, lsr #1
 	teqne	r2, ip, lsr #1
 	beq	3f
 
-	@ Test for equality.
-	@ Note that 0.0 is equal to -0.0.
+	@ Test for equality.  The representations of +0.0 and -0.0
+	@ have all bits set to zero, except for the sign bit.  Since
+	@ 0.0 is equal to -0.0, we begin by testing 
+	@ ((r0 | r1) & ~0x8000000).
 2:	orr	r3, r0, r1
+	@ If the result of the bitwise and is zero, then the Z flag
+	@ will be set.  In any case, the C flag will be set.
 	bics	r3, r3, #0x80000000	@ either 0.0 or -0.0
 	teqne	r0, r1			@ or both the same
+	@ If the Z flag is set, the two operands were equal.  Return zero.
 	moveq	r0, #0
 	RETc(eq)
 
-	@ Check for sign difference.  The N flag is set if it is the case.
-	@ If so, return sign of r0.
+	@ Check for sign difference.  The N flag is set (due to the
+	@ use of teq above) if the sign bit is set on exactly one
+	@ of the operands.  Return the sign of the first operand.
 	movmi	r0, r0, asr #31
 	orrmi	r0, r0, #1
 	RETc(mi)
@@ -686,12 +732,24 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
 	@ Compare mantissa if exponents are equal
 	moveq	r0, r0, lsl #9
 	cmpeq	r0, r1, lsl #9
+
+	@ We know the operands cannot be equal at this point, so the
+	@ Z flag is clear.  The C flag is set if the first operand has
+	@ the greater exponent, or the exponents are equal and the 
+	@ first operand has the greater mantissa.  Therefore, if the C
+	@ flag is set, the first operand is greater iff the sign is
+	@ positive.  These next two instructions will put zero in
+	@ r0 if the first operand is greater, and -1 if the second
+	@ operand is greater.
 	movcs	r0, r1, asr #31
 	mvncc	r0, r1, asr #31
+	@ If r0 is 0, the first operand is greater, so return 1.  Leave
+	@ -1 unchanged.
 	orr	r0, r0, #1
 	RET
 
-	@ Look for a NAN. 
+	@ We know that at least one argument is either Inf or NaN.
+	@ Look for a NaN. 
 3:	and	r2, r1, ip, lsr #1
 	teq	r2, ip, lsr #1
 	bne	4f
@@ -702,7 +760,8 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
 	bne	2b
 	movs	ip, r0, lsl #9
 	beq	2b			@ r0 is not NAN
-5:	mov	r0, r3			@ return unordered code from r3.
+5:	@ The Z flag is clear at this point.
+	mov	r0, r3			@ return unordered code from r3.
 	RET
 
 	FUNC_END gesf2
@@ -713,11 +772,75 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
 	FUNC_END eqsf2
 	FUNC_END cmpsf2
 
+ARM_FUNC_START aeabi_cfrcmple
+	mov	ip, r0
+	mov	r0, r1
+	mov	r1, ip
+	b	6f
+	
+ARM_FUNC_START aeabi_cfcmpeq
+ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq
+	@ The status-returning routines are required to preserve all
+	@ registers except ip, lr, and cpsr.
+6:	stmfd	sp!, {r0, r1, r2, r3, lr}
+	ARM_CALL cmpsf2
+	@ Set the Z flag correctly, and the C flag unconditionally.
+	cmp	 r0, #0
+	@ Clear the C flag if the return value was -1, indicating
+	@ that the first operand was smaller than the second.
+	cmnmi	 r0, #0
+	RETLDM  "r0, r1, r2, r3"
+	FUNC_END aeabi_cfcmple
+	FUNC_END aeabi_cfcmpeq
+	
+ARM_FUNC_START	aeabi_fcmpeq
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cfcmple
+	moveq	r0, #1	@ Equal to.
+	movne	r0, #0	@ Less than, greater than, or unordered.
+	RETLDM
+	FUNC_END aeabi_fcmpeq
+
+ARM_FUNC_START	aeabi_fcmplt
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cfcmple
+	movcc	r0, #1	@ Less than.
+	movcs	r0, #0	@ Equal to, greater than, or unordered.
+	RETLDM
+	FUNC_END aeabi_fcmplt
+
+ARM_FUNC_START	aeabi_fcmple
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cfcmple
+	movls	r0, #1  @ Less than or equal to.
+	movhi	r0, #0	@ Greater than or unordered.
+	RETLDM
+	FUNC_END aeabi_fcmple
+
+ARM_FUNC_START	aeabi_fcmpge
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cfrcmple
+	movls	r0, #1	@ Operand 2 is less than or equal to operand 1.
+	movhi	r0, #0	@ Operand 2 greater than operand 1, or unordered.
+	RETLDM
+	FUNC_END aeabi_fcmpge
+
+ARM_FUNC_START	aeabi_fcmpgt
+	str	lr, [sp, #-4]!
+	ARM_CALL aeabi_cfrcmple
+	movcc	r0, #1	@ Operand 2 is less than operand 1.
+	movcs	r0, #0  @ Operand 2 is greater than or equal to operand 1,
+			@ or they are unordered.
+	RETLDM
+	FUNC_END aeabi_fcmpgt
+		
 #endif /* L_cmpsf2 */
 
 #ifdef L_unordsf2
 
 ARM_FUNC_START unordsf2
+ARM_FUNC_ALIAS aeabi_fcmpun unordsf2
+	
 	mov	ip, #0xff000000
 	and	r2, r1, ip, lsr #1
 	teq	r2, ip, lsr #1
@@ -734,6 +857,7 @@ ARM_FUNC_START unordsf2
 3:	mov	r0, #1			@ arguments are unordered.
 	RET
 
+	FUNC_END aeabi_fcmpun
 	FUNC_END unordsf2
 
 #endif /* L_unordsf2 */
@@ -741,6 +865,7 @@ ARM_FUNC_START unordsf2
 #ifdef L_fixsfsi
 
 ARM_FUNC_START fixsfsi
+ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
 	movs	r0, r0, lsl #1
 	RETc(eq)			@ value is 0.
 
@@ -774,6 +899,7 @@ ARM_FUNC_START fixsfsi
 3:	mov	r0, #0			@ What should we convert NAN to?
 	RET
 
+	FUNC_END aeabi_f2iz
 	FUNC_END fixsfsi
 
 #endif /* L_fixsfsi */
@@ -781,6 +907,7 @@ ARM_FUNC_START fixsfsi
 #ifdef L_fixunssfsi
 
 ARM_FUNC_START fixunssfsi
+ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi
 	movs	r0, r0, lsl #1
 	movcss	r0, #0			@ value is negative...
 	RETc(eq)			@ ... or 0.
@@ -811,6 +938,7 @@ ARM_FUNC_START fixunssfsi
 3:	mov	r0, #0			@ What should we convert NAN to?
 	RET
 
+	FUNC_END aeabi_f2uiz
 	FUNC_END fixunssfsi
 
 #endif /* L_fixunssfsi */
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
index 9f8b4673702b..cea093c9e25f 100644
--- a/gcc/config/arm/lib1funcs.asm
+++ b/gcc/config/arm/lib1funcs.asm
@@ -199,6 +199,9 @@ SYM (__\name):
 _L__\name:		/* A hook to tell gdb that we've switched to ARM */
 .endm
 #define EQUIV .thumb_set
+.macro  ARM_CALL name
+	bl	_L__\name
+.endm
 #else
 .macro	ARM_FUNC_START name
 	.text
@@ -209,6 +212,9 @@ _L__\name:		/* A hook to tell gdb that we've switched to ARM */
 SYM (__\name):
 .endm
 #define EQUIV .set
+.macro  ARM_CALL name
+	bl	__\name
+.endm
 #endif
 
 .macro	ARM_FUNC_ALIAS new old
@@ -649,6 +655,15 @@ LSYM(Lgot_result):
 
 	DIV_FUNC_END udivsi3
 
+ARM_FUNC_START aeabi_uidivmod
+	stmfd	sp!, { r0, r1, lr }
+	ARM_CALL udivsi3
+	ldmfd	sp!, { r1, r2, lr }
+	mul	r3, r2, r0
+	sub	r1, r1, r3
+	RET
+	FUNC_END aeabi_uidivmod
+	
 #endif /* L_udivsi3 */
 /* ------------------------------------------------------------------------ */
 #ifdef L_umodsi3
@@ -769,6 +784,15 @@ LSYM(Lover12):
 	
 	DIV_FUNC_END divsi3
 
+ARM_FUNC_START aeabi_idivmod
+	stmfd	sp!, { r0, r1, lr }
+	ARM_CALL divsi3
+	ldmfd	sp!, { r1, r2, lr }
+	mul	r3, r2, r0
+	sub	r1, r1, r3
+	RET
+	FUNC_END aeabi_idivmod
+	
 #endif /* L_divsi3 */
 /* ------------------------------------------------------------------------ */
 #ifdef L_modsi3
@@ -834,9 +858,13 @@ LSYM(Lover12):
 #ifdef L_dvmd_tls
 
 	FUNC_START div0
+	ARM_FUNC_ALIAS aeabi_idiv0 div0
+	ARM_FUNC_ALIAS aeabi_ldiv0 div0
 
 	RET
 
+	FUNC_END aeabi_ldiv0
+	FUNC_END aeabi_idiv0
 	FUNC_END div0
 	
 #endif /* L_divmodsi_tools */
@@ -884,7 +912,8 @@ LSYM(Lover12):
 #ifdef L_lshrdi3
 
 	FUNC_START lshrdi3
-
+	ARM_FUNC_ALIAS aeabi_llsr lshrdi3
+	
 #ifdef __thumb__
 	lsr	al, r2
 	mov	r3, ah
@@ -907,6 +936,7 @@ LSYM(Lover12):
 	mov	ah, ah, lsr r2
 	RET
 #endif
+	FUNC_END aeabi_llsr
 	FUNC_END lshrdi3
 
 #endif
@@ -914,6 +944,8 @@ LSYM(Lover12):
 #ifdef L_ashrdi3
 	
 	FUNC_START ashrdi3
+	ARM_FUNC_ALIAS aeabi_lasr ashrdi3
+	
 #ifdef __thumb__
 	lsr	al, r2
 	mov	r3, ah
@@ -941,6 +973,7 @@ LSYM(Lover12):
 	RET
 #endif
 
+	FUNC_END aeabi_lasr
 	FUNC_END ashrdi3
 
 #endif
@@ -948,6 +981,8 @@ LSYM(Lover12):
 #ifdef L_ashldi3
 
 	FUNC_START ashldi3
+	ARM_FUNC_ALIAS aeabi_llsl ashldi3
+	
 #ifdef __thumb__
 	lsl	ah, r2
 	mov	r3, al
@@ -970,6 +1005,7 @@ LSYM(Lover12):
 	mov	al, al, lsl r2
 	RET
 #endif
+	FUNC_END aeabi_llsl
 	FUNC_END ashldi3
 
 #endif
@@ -1104,4 +1140,4 @@ LSYM(Lchange_\register):
 
 #include "ieee754-df.S"
 #include "ieee754-sf.S"
-
+#include "bpabi.S"
diff --git a/gcc/config/arm/libgcc-bpabi.ver b/gcc/config/arm/libgcc-bpabi.ver
new file mode 100644
index 000000000000..788e3ad2b1ff
--- /dev/null
+++ b/gcc/config/arm/libgcc-bpabi.ver
@@ -0,0 +1,63 @@
+GCC_3.5 {
+  # BPABI symbols
+  __aeabi_cdcmpeq
+  __aeabi_cdcmple
+  __aeabi_cdrcmple
+  __aeabi_cfcmpeq
+  __aeabi_cfcmple
+  __aeabi_cfrcmple
+  __aeabi_d2f
+  __aeabi_d2iz
+  __aeabi_d2lz
+  __aeabi_d2uiz
+  __aeabi_d2ulz
+  __aeabi_dadd
+  __aeabi_dcmpeq
+  __aeabi_dcmpge
+  __aeabi_dcmpgt
+  __aeabi_dcmple
+  __aeabi_dcmplt
+  __aeabi_dcmpun
+  __aeabi_ddiv
+  __aeabi_dmul
+  __aeabi_dneg
+  __aeabi_drsub
+  __aeabi_dsub
+  __aeabi_f2d
+  __aeabi_f2iz
+  __aeabi_f2lz
+  __aeabi_f2uiz
+  __aeabi_f2ulz
+  __aeabi_fadd
+  __aeabi_fcmpeq
+  __aeabi_fcmpge
+  __aeabi_fcmpgt
+  __aeabi_fcmple
+  __aeabi_fcmplt
+  __aeabi_fcmpun
+  __aeabi_fdiv
+  __aeabi_fmul
+  __aeabi_fneg
+  __aeabi_frsub
+  __aeabi_fsub
+  __aeabi_i2d
+  __aeabi_i2f
+  __aeabi_idiv0
+  __aeabi_idivmod
+  __aeabi_l2d
+  __aeabi_l2f
+  __aeabi_lasr
+  __aeabi_lcmp
+  __aeabi_ldiv0
+  __aeabi_ldivmod
+  __aeabi_llsl
+  __aeabi_llsr
+  __aeabi_lmul
+  __aeabi_ui2d
+  __aeabi_ui2f
+  __aeabi_uidivmod
+  __aeabi_uldivmod
+  __aeabi_ulcmp
+  __aeabi_ul2d
+  __aeabi_ul2f
+}
diff --git a/gcc/config/arm/symbian.h b/gcc/config/arm/symbian.h
index c03b428e692a..bd647d39f0ce 100644
--- a/gcc/config/arm/symbian.h
+++ b/gcc/config/arm/symbian.h
@@ -20,9 +20,6 @@
    the Free Software Foundation, 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-/* Use the SYMBIAN ABI by default.  */
-#define ARM_DEFAULT_ABI ARM_ABI_AAPCS
-
 /* Do not expand builtin functions (unless explicitly prefixed with
    "__builtin").  Symbian OS code relies on properties of the standard
    library that go beyond those guaranteed by the ANSI/ISO standard.
@@ -53,11 +50,5 @@
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC "crti%O%s crtbegin%O%s"
 
-/* The generic link spec in elf.h does not support shared libraries.  */
-#undef LINK_SPEC
-#define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} "		\
-  "%{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} "	\
-  "-X"
-
 /* Support the "dllimport" attribute.  */
 #define TARGET_DLLIMPORT_DECL_ATTRIBUTES 1
diff --git a/gcc/config/arm/t-bpabi b/gcc/config/arm/t-bpabi
new file mode 100644
index 000000000000..74445ddc92e3
--- /dev/null
+++ b/gcc/config/arm/t-bpabi
@@ -0,0 +1,9 @@
+# Add the bpabi.S functions.
+LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod
+
+# Add the BPABI C functions.
+LIB2FUNCS_EXTRA = $(srcdir)/config/arm/bpabi.c
+
+# Add the BPABI names.
+SHLIB_MAPFILES += $(srcdir)/config/arm/libgcc-bpabi.ver
+
diff --git a/gcc/defaults.h b/gcc/defaults.h
index a1e5300a006a..ef8469c2dfaf 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -627,6 +627,19 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
 #define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) false
 #endif
 
+/* True if the target should use the standard libgcc arithmetic
+   library functions, like __addsi3 and _fixdfdi.  */
+#ifndef TARGET_LIBGCC_LIBFUNCS
+#define TARGET_LIBGCC_LIBFUNCS (true)
+#endif
+
+/* True if the targets integer-comparision fucntions return { 0, 1, 2
+   } to indicate { <, ==, > }.  False if { -1, 0, 1 } is used
+   instead.  The libgcc routines are biased.  */
+#ifndef TARGET_LIB_INT_CMP_BIASED
+#define TARGET_LIB_INT_CMP_BIASED (true)
+#endif
+
 /* If FLOAT_WORDS_BIG_ENDIAN is not defined in the header files,
    then the word-endianness is the same as for integers.  */
 #ifndef FLOAT_WORDS_BIG_ENDIAN
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 5192bd6e0aae..06c08f99c45c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4765,6 +4765,24 @@ comparison operators, so the default returns false always.  Most ports
 don't need to define this macro.
 @end defmac
 
+@defmac TARGET_LIBGCC_FUNCS
+This macro should evaluate to @code{true} if the standard GCC library
+names (like @code{__modsi3}) should be used for functions provided in
+@file{libgcc.a}.  If this macro evaluates to @code{false}, then the
+target must explictily set the names of all desired library functions
+itself using the @code{TARGET_INIT_LIBFUNCS} hook.
+@end defmac
+
+@defmac TARGET_LIB_INT_CMP_BIASED
+This macro should evaluate to @code{true} if the integer comparison
+functions (like @code{__cmpdi2}) return 0 to indicate that the first
+operand is smaller than the second, 1 to indicate that they are equal,
+and 2 to indicate that the first operand is greater than the second.
+If this macro evalutes to @code{false} the comparison functions return
+-1, 0, and 1 instead of 0, 1, and 2.  If the target uses the routines
+in @file{libgcc.a}, you do not need to define this macro.
+@end defmac
+
 @cindex US Software GOFAST, floating point emulation library
 @cindex floating point emulation library, US Software GOFAST
 @cindex GOFAST, floating point emulation library
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 735fe987fc16..7ee5964853b7 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -4337,10 +4337,24 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
 	target = 0;
 
       if (quotient == 0)
-	/* No divide instruction either.  Use library for remainder.  */
-	remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab,
-				       op0, op1, target,
-				       unsignedp, OPTAB_LIB_WIDEN);
+	{
+	  /* No divide instruction either.  Use library for remainder.  */
+	  remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab,
+					 op0, op1, target,
+					 unsignedp, OPTAB_LIB_WIDEN);
+	  /* No remainder function.  Try a quotient-and-remainder
+	     function, keeping the remainder.  */
+	  if (!remainder)
+	    {
+	      remainder = gen_reg_rtx (compute_mode);
+	      if (!expand_twoval_binop_libfunc 
+		  (unsignedp ? udivmod_optab : sdivmod_optab,
+		   op0, op1,
+		   NULL_RTX, remainder,
+		   unsignedp ? UMOD : MOD))
+		remainder = NULL_RTX;
+	    }
+	}
       else
 	{
 	  /* We divided.  Now finish doing X - Y * (X / Y).  */
diff --git a/gcc/gthr.h b/gcc/gthr.h
index cf284229f5f3..22b2ecd0ca44 100644
--- a/gcc/gthr.h
+++ b/gcc/gthr.h
@@ -102,6 +102,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "gthr-single.h"
 #endif
 
-#pragma GCC visibility pop(default)
+#pragma GCC visibility pop
 
 #endif /* ! GCC_GTHR_H */
diff --git a/gcc/optabs.c b/gcc/optabs.c
index b76e952a954c..ab826769fad9 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -2448,6 +2448,55 @@ expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
   delete_insns_since (entry_last);
   return 0;
 }
+
+/* Expand the two-valued library call indicated by BINOPTAB, but
+   preserve only one of the values.  If TARG0 is non-NULL, the first
+   value is placed into TARG0; otherwise the second value is placed
+   into TARG1.  Exactly one of TARG0 and TARG1 must be non-NULL.  The
+   value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
+   This routine assumes that the value returned by the library call is
+   as if the return value was of an integral mode twice as wide as the
+   mode of OP0.  Returns 1 if the call was successful.  */
+
+bool
+expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1, 
+			     rtx targ0, rtx targ1, enum rtx_code code)
+{
+  enum machine_mode mode;
+  enum machine_mode libval_mode;
+  rtx libval;
+  rtx insns;
+  
+  /* Exactly one of TARG0 or TARG1 should be non-NULL.  */
+  if (!((targ0 != NULL_RTX) ^ (targ1 != NULL_RTX)))
+    abort ();
+
+  mode = GET_MODE (op0);
+  if (!binoptab->handlers[(int) mode].libfunc)
+    return false;
+
+  /* The value returned by the library function will have twice as
+     many bits as the nominal MODE.  */
+  libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode), 
+					MODE_INT);
+  start_sequence ();
+  libval = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
+				    NULL_RTX, LCT_CONST, 
+				    libval_mode, 2,
+				    op0, mode, 
+				    op1, mode);
+  /* Get the part of VAL containing the value that we want.  */
+  libval = simplify_gen_subreg (mode, libval, libval_mode,
+				targ0 ? 0 : GET_MODE_SIZE (mode));
+  insns = get_insns ();
+  end_sequence ();
+  /* Move the into the desired location.  */
+  emit_libcall_block (insns, targ0 ? targ0 : targ1, libval, 
+		      gen_rtx_fmt_ee (code, mode, op0, op1));
+  
+  return true;
+}
+
 
 /* Wrapper around expand_unop which takes an rtx code to specify
    the operation to perform, not an optab pointer.  All other
@@ -3817,12 +3866,19 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
 					word_mode, 2, x, mode, y, mode);
 
-      /* Integer comparison returns a result that must be compared against 1,
-	 so that even if we do an unsigned compare afterward,
-	 there is still a value that can represent the result "less than".  */
       *px = result;
-      *py = const1_rtx;
       *pmode = word_mode;
+      if (TARGET_LIB_INT_CMP_BIASED)
+	/* Integer comparison returns a result that must be compared
+	   against 1, so that even if we do an unsigned compare
+	   afterward, there is still a value that can represent the
+	   result "less than".  */
+	*py = const1_rtx;
+      else
+	{
+	  *py = const0_rtx;
+	  *punsignedp = 1;
+	}
       return;
     }
 
@@ -3993,12 +4049,14 @@ prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
 {
   enum rtx_code comparison = *pcomparison;
   enum rtx_code swapped = swap_condition (comparison);
+  enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
   rtx x = *px;
   rtx y = *py;
   enum machine_mode orig_mode = GET_MODE (x);
   enum machine_mode mode;
   rtx value, target, insns, equiv;
   rtx libfunc = 0;
+  bool reversed_p = false;
 
   for (mode = orig_mode; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
     {
@@ -4012,8 +4070,16 @@ prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
 	  comparison = swapped;
 	  break;
 	}
-    }
 
+      if ((libfunc = code_to_optab[reversed]->handlers[mode].libfunc)
+	  && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
+	{
+	  comparison = reversed;
+	  reversed_p = true;
+	  break;
+	}
+    }
+ 
   if (mode == VOIDmode)
     abort ();
 
@@ -4089,10 +4155,9 @@ prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
   target = gen_reg_rtx (word_mode);
   emit_libcall_block (insns, target, value, equiv);
 
-
   if (comparison == UNORDERED
       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
-    comparison = NE;
+    comparison = reversed_p ? EQ : NE;
 
   *px = target;
   *py = const0_rtx;
@@ -5418,72 +5483,79 @@ init_optabs (void)
   init_all_optabs ();
 
   /* Initialize the optabs with the names of the library functions.  */
-  init_integral_libfuncs (add_optab, "add", '3');
-  init_floating_libfuncs (add_optab, "add", '3');
-  init_integral_libfuncs (addv_optab, "addv", '3');
-  init_floating_libfuncs (addv_optab, "add", '3');
-  init_integral_libfuncs (sub_optab, "sub", '3');
-  init_floating_libfuncs (sub_optab, "sub", '3');
-  init_integral_libfuncs (subv_optab, "subv", '3');
-  init_floating_libfuncs (subv_optab, "sub", '3');
-  init_integral_libfuncs (smul_optab, "mul", '3');
-  init_floating_libfuncs (smul_optab, "mul", '3');
-  init_integral_libfuncs (smulv_optab, "mulv", '3');
-  init_floating_libfuncs (smulv_optab, "mul", '3');
-  init_integral_libfuncs (sdiv_optab, "div", '3');
-  init_floating_libfuncs (sdiv_optab, "div", '3');
-  init_integral_libfuncs (sdivv_optab, "divv", '3');
-  init_integral_libfuncs (udiv_optab, "udiv", '3');
-  init_integral_libfuncs (sdivmod_optab, "divmod", '4');
-  init_integral_libfuncs (udivmod_optab, "udivmod", '4');
-  init_integral_libfuncs (smod_optab, "mod", '3');
-  init_integral_libfuncs (umod_optab, "umod", '3');
-  init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
-  init_integral_libfuncs (and_optab, "and", '3');
-  init_integral_libfuncs (ior_optab, "ior", '3');
-  init_integral_libfuncs (xor_optab, "xor", '3');
-  init_integral_libfuncs (ashl_optab, "ashl", '3');
-  init_integral_libfuncs (ashr_optab, "ashr", '3');
-  init_integral_libfuncs (lshr_optab, "lshr", '3');
-  init_integral_libfuncs (smin_optab, "min", '3');
-  init_floating_libfuncs (smin_optab, "min", '3');
-  init_integral_libfuncs (smax_optab, "max", '3');
-  init_floating_libfuncs (smax_optab, "max", '3');
-  init_integral_libfuncs (umin_optab, "umin", '3');
-  init_integral_libfuncs (umax_optab, "umax", '3');
-  init_integral_libfuncs (neg_optab, "neg", '2');
-  init_floating_libfuncs (neg_optab, "neg", '2');
-  init_integral_libfuncs (negv_optab, "negv", '2');
-  init_floating_libfuncs (negv_optab, "neg", '2');
-  init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
-  init_integral_libfuncs (ffs_optab, "ffs", '2');
-  init_integral_libfuncs (clz_optab, "clz", '2');
-  init_integral_libfuncs (ctz_optab, "ctz", '2');
-  init_integral_libfuncs (popcount_optab, "popcount", '2');
-  init_integral_libfuncs (parity_optab, "parity", '2');
-
-  /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
-  init_integral_libfuncs (cmp_optab, "cmp", '2');
-  init_integral_libfuncs (ucmp_optab, "ucmp", '2');
-  init_floating_libfuncs (cmp_optab, "cmp", '2');
-
-  /* EQ etc are floating point only.  */
-  init_floating_libfuncs (eq_optab, "eq", '2');
-  init_floating_libfuncs (ne_optab, "ne", '2');
-  init_floating_libfuncs (gt_optab, "gt", '2');
-  init_floating_libfuncs (ge_optab, "ge", '2');
-  init_floating_libfuncs (lt_optab, "lt", '2');
-  init_floating_libfuncs (le_optab, "le", '2');
-  init_floating_libfuncs (unord_optab, "unord", '2');
-
-  /* Conversions.  */
-  init_interclass_conv_libfuncs (sfloat_optab, "float", MODE_INT, MODE_FLOAT);
-  init_interclass_conv_libfuncs (sfix_optab, "fix",     MODE_FLOAT, MODE_INT);
-  init_interclass_conv_libfuncs (ufix_optab, "fixuns",  MODE_FLOAT, MODE_INT);
-
-  /* sext_optab is also used for FLOAT_EXTEND.  */
-  init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
-  init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
+  if (TARGET_LIBGCC_LIBFUNCS)
+    {
+      init_integral_libfuncs (add_optab, "add", '3');
+      init_floating_libfuncs (add_optab, "add", '3');
+      init_integral_libfuncs (addv_optab, "addv", '3');
+      init_floating_libfuncs (addv_optab, "add", '3');
+      init_integral_libfuncs (sub_optab, "sub", '3');
+      init_floating_libfuncs (sub_optab, "sub", '3');
+      init_integral_libfuncs (subv_optab, "subv", '3');
+      init_floating_libfuncs (subv_optab, "sub", '3');
+      init_integral_libfuncs (smul_optab, "mul", '3');
+      init_floating_libfuncs (smul_optab, "mul", '3');
+      init_integral_libfuncs (smulv_optab, "mulv", '3');
+      init_floating_libfuncs (smulv_optab, "mul", '3');
+      init_integral_libfuncs (sdiv_optab, "div", '3');
+      init_floating_libfuncs (sdiv_optab, "div", '3');
+      init_integral_libfuncs (sdivv_optab, "divv", '3');
+      init_integral_libfuncs (udiv_optab, "udiv", '3');
+      init_integral_libfuncs (sdivmod_optab, "divmod", '4');
+      init_integral_libfuncs (udivmod_optab, "udivmod", '4');
+      init_integral_libfuncs (smod_optab, "mod", '3');
+      init_integral_libfuncs (umod_optab, "umod", '3');
+      init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
+      init_integral_libfuncs (and_optab, "and", '3');
+      init_integral_libfuncs (ior_optab, "ior", '3');
+      init_integral_libfuncs (xor_optab, "xor", '3');
+      init_integral_libfuncs (ashl_optab, "ashl", '3');
+      init_integral_libfuncs (ashr_optab, "ashr", '3');
+      init_integral_libfuncs (lshr_optab, "lshr", '3');
+      init_integral_libfuncs (smin_optab, "min", '3');
+      init_floating_libfuncs (smin_optab, "min", '3');
+      init_integral_libfuncs (smax_optab, "max", '3');
+      init_floating_libfuncs (smax_optab, "max", '3');
+      init_integral_libfuncs (umin_optab, "umin", '3');
+      init_integral_libfuncs (umax_optab, "umax", '3');
+      init_integral_libfuncs (neg_optab, "neg", '2');
+      init_floating_libfuncs (neg_optab, "neg", '2');
+      init_integral_libfuncs (negv_optab, "negv", '2');
+      init_floating_libfuncs (negv_optab, "neg", '2');
+      init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
+      init_integral_libfuncs (ffs_optab, "ffs", '2');
+      init_integral_libfuncs (clz_optab, "clz", '2');
+      init_integral_libfuncs (ctz_optab, "ctz", '2');
+      init_integral_libfuncs (popcount_optab, "popcount", '2');
+      init_integral_libfuncs (parity_optab, "parity", '2');
+
+      /* Comparison libcalls for integers MUST come in pairs,
+	 signed/unsigned.  */
+      init_integral_libfuncs (cmp_optab, "cmp", '2');
+      init_integral_libfuncs (ucmp_optab, "ucmp", '2');
+      init_floating_libfuncs (cmp_optab, "cmp", '2');
+
+      /* EQ etc are floating point only.  */
+      init_floating_libfuncs (eq_optab, "eq", '2');
+      init_floating_libfuncs (ne_optab, "ne", '2');
+      init_floating_libfuncs (gt_optab, "gt", '2');
+      init_floating_libfuncs (ge_optab, "ge", '2');
+      init_floating_libfuncs (lt_optab, "lt", '2');
+      init_floating_libfuncs (le_optab, "le", '2');
+      init_floating_libfuncs (unord_optab, "unord", '2');
+
+      /* Conversions.  */
+      init_interclass_conv_libfuncs (sfloat_optab, "float", 
+				     MODE_INT, MODE_FLOAT);
+      init_interclass_conv_libfuncs (sfix_optab, "fix",     
+				     MODE_FLOAT, MODE_INT);
+      init_interclass_conv_libfuncs (ufix_optab, "fixuns",  
+				     MODE_FLOAT, MODE_INT);
+
+      /* sext_optab is also used for FLOAT_EXTEND.  */
+      init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
+      init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
+    }
 
   /* Use cabs for double complex abs, since systems generally have cabs.
      Don't define any libcall for float complex, so that cabs will be used.  */
@@ -5530,6 +5602,64 @@ init_optabs (void)
   /* Allow the target to add more libcalls or rename some, etc.  */
   targetm.init_libfuncs ();
 }
+
+#ifdef DEBUG
+
+/* Print information about the current contents of the optabs on
+   STDERR.  */
+
+static void
+debug_optab_libfuncs (void)
+{
+  int i;
+  int j;
+  int k;
+
+  /* Dump the arithmetic optabs.  */
+  for (i = 0; i != (int) OTI_MAX; i++) 
+    for (j = 0; j < NUM_MACHINE_MODES; ++j)
+      {
+	optab o;
+	struct optab_handlers *h;
+
+	o = optab_table[i];
+	h = &o->handlers[j];
+	if (h->libfunc)
+	  {
+	    if (GET_CODE (h->libfunc) != SYMBOL_REF)
+	      abort ();
+	    fprintf (stderr, "%s\t%s:\t%s\n", 
+		     GET_RTX_NAME (o->code),
+		     GET_MODE_NAME (j),
+		     XSTR (h->libfunc, 0));
+	  }
+      }
+
+  /* Dump the conversion optabs.  */
+  for (i = 0; i < (int) CTI_MAX; ++i)
+    for (j = 0; j < NUM_MACHINE_MODES; ++j)
+      for (k = 0; k < NUM_MACHINE_MODES; ++k)
+	{
+	  convert_optab o;
+	  struct optab_handlers *h;
+
+	  o = &convert_optab_table[i];
+	  h = &o->handlers[j][k];
+	  if (h->libfunc)
+	    {
+	      if (GET_CODE (h->libfunc) != SYMBOL_REF)
+		abort ();
+	      fprintf (stderr, "%s\t%s\t%s:\t%s\n", 
+		       GET_RTX_NAME (o->code),
+		       GET_MODE_NAME (j),
+		       GET_MODE_NAME (k),
+		       XSTR (h->libfunc, 0));
+	    }
+	}
+}
+
+#endif /* DEBUG */
+
 
 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
    CODE.  Return 0 on failure.  */
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 2e24c2450214..24c3c8849406 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -417,6 +417,11 @@ extern int expand_twoval_unop (optab, rtx, rtx, rtx, int);
 /* Generate code to perform an operation on two operands with two results.  */
 extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
 
+/* Generate code to perform an operation on two operands with two
+   results, using a library function.  */
+extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx, 
+					 enum rtx_code);
+
 /* Expand a unary arithmetic operation given optab rtx operand.  */
 extern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int);
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 022280c2ea92..459f7b50cc7d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2004-08-09  Mark Mitchell  <mark@codesourcery.com>
+
+	* gcc.dg/testsuite/gcc.dg/arm-eabi1.c: New test.
+	* gcc.dg/dll-2.c: Fix dg-require syntax.
+	* gcc.misc-tests/arm-isr.c (abort): Declare.
+	(exit): Likewise.
+
 2004-08-10  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/16971
diff --git a/gcc/testsuite/gcc.dg/arm-eabi1.c b/gcc/testsuite/gcc.dg/arm-eabi1.c
new file mode 100644
index 000000000000..0df295aa7268
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/arm-eabi1.c
@@ -0,0 +1,235 @@
+/* { dg-do run { target arm*-*-symbianelf* arm*-*-eabi* } } */
+/* { dg-options "" } */
+
+/* This file tests most of the non-C++ run-time helper functions
+   described in Section 4 of the "Run-Time ABI for the ARM
+   Architecture".  These are basic tests; they do not try to validate
+   all of the corner cases in these routines.  
+
+   The functions not tested here are:
+
+     __aeabi_cdcmpeq
+     __aeabi_cdcmple
+     __aeabi_cdrcmple
+     __aeabi_cfcmpeq
+     __aeabi_cfcmple
+     __aeabi_cfrcmple
+     __aeabi_ldivmod
+     __aeabi_uldivmod
+     __aeabi_idivmod
+     __aeabi_uidivmod
+
+   These functions have non-standard calling conventions that would
+   require the use of inline assembly to test.  It would be good to
+   add such tests, but they have not yet been implemented.  
+
+   There are also no tests for the "division by zero", "unaligned
+   memory access", "memory copying, clearing, and setting"
+   functions.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#define decl_float(code, type)					\
+  extern type __aeabi_ ## code ## add (type, type);		\
+  extern type __aeabi_ ## code ## div (type, type);		\
+  extern type __aeabi_ ## code ## mul (type, type);		\
+  extern type __aeabi_ ## code ## neg (type);			\
+  extern type __aeabi_ ## code ## rsub (type, type);		\
+  extern type __aeabi_ ## code ## sub (type, type);		\
+  extern int __aeabi_ ## code ## cmpeq (type, type);		\
+  extern int __aeabi_ ## code ## cmplt (type, type);		\
+  extern int __aeabi_ ## code ## cmple (type, type);		\
+  extern int __aeabi_ ## code ## cmpge (type, type);		\
+  extern int __aeabi_ ## code ## cmpgt (type, type);		\
+  extern int __aeabi_ ## code ## cmpun (type, type);		\
+  extern int __aeabi_ ## code ## 2iz (type);			\
+  extern unsigned int __aeabi_ ## code ## 2uiz (type);		\
+  extern long long __aeabi_ ## code ## 2lz (type);		\
+  extern unsigned long long __aeabi_ ## code ## 2ulz (type);	\
+  extern type __aeabi_i2 ## code (int);				\
+  extern type __aeabi_ui2 ## code (int);			\
+  extern type __aeabi_l2 ## code (long long);			\
+  extern type __aeabi_ul2 ## code (unsigned long long);		\
+								\
+  type code ## zero = 0.0;					\
+  type code ## one = 1.0;					\
+  type code ## two = 2.0;					\
+  type code ## four = 4.0;					\
+  type code ## minus_one = -1.0;				\
+  type code ## minus_two = -2.0;				\
+  type code ## minus_four = -4.0;				\
+  type code ## epsilon = 1E-32;					\
+  type code ## NaN = 0.0 / 0.0;				
+
+decl_float (d, double)
+decl_float (f, float)
+
+extern float __aeabi_d2f (double);
+extern double __aeabi_f2d (float);
+extern long long __aeabi_lmul (long long, long long);
+extern long long __aeabi_llsl (long long, int);
+extern long long __aeabi_llsr (long long, int);
+extern long long __aeabi_lasr (long long, int);
+extern int __aeabi_lcmp (long long, long long);
+extern int __aeabi_ulcmp (unsigned long long, unsigned long long);
+
+#define eq(a, b, type, abs, epsilon, format)			\
+  {								\
+    type a1;							\
+    type b1;							\
+								\
+    fprintf (stderr, "%d: Test %s == %s\n", __LINE__, #a, #b);	\
+    a1 = a;							\
+    b1 = b;							\
+    if (abs (a1 - b1) > epsilon)				\
+    {								\
+      fprintf (stderr, "%d: " format " != " format "\n",	\
+	       __LINE__, a1, b1);				\
+      abort ();							\
+    }								\
+  }
+
+#define ieq(a, b) eq (a, b, int, abs, 0, "%d")
+#define ueq(a, b) eq (a, b, unsigned int, abs, 0, "%u")
+#define leq(a, b) eq (a, b, long long, abs, 0, "%lld")
+#define uleq(a, b) eq (a, b, unsigned long long, abs, 0, "%llu")
+#define feq(a, b) eq (a, b, float, fabs, fepsilon, "%f")
+#define deq(a, b) eq (a, b, double, fabs, depsilon, "%g")
+
+int main () {
+  /* Table 2.  Double-precision floating-point arithmetic.  */
+  deq (__aeabi_dadd (dzero, done), done);
+  deq (__aeabi_dadd (done, done), dtwo);
+  deq (__aeabi_ddiv (dminus_four, dminus_two), dtwo);
+  deq (__aeabi_ddiv (dminus_two, dtwo), dminus_one);
+  deq (__aeabi_dmul (dtwo, dtwo), dfour);
+  deq (__aeabi_dmul (dminus_one, dminus_two), dtwo);
+  deq (__aeabi_dneg (dminus_one), done);
+  deq (__aeabi_dneg (dfour), dminus_four);
+  deq (__aeabi_drsub (done, dzero), dminus_one);
+  deq (__aeabi_drsub (dtwo, dminus_two), dminus_four);
+  deq (__aeabi_dsub (dzero, done), dminus_one);
+  deq (__aeabi_dsub (dminus_two, dtwo), dminus_four);
+
+  /* Table 3.  Double-precision floating-point comparisons.  */
+  ieq (__aeabi_dcmpeq (done, done), 1);
+  ieq (__aeabi_dcmpeq (done, dzero), 0);
+  ieq (__aeabi_dcmpeq (dNaN, dzero), 0);
+  ieq (__aeabi_dcmpeq (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmplt (dzero, done), 1);
+  ieq (__aeabi_dcmplt (done, dzero), 0);
+  ieq (__aeabi_dcmplt (dzero, dzero), 0);
+  ieq (__aeabi_dcmplt (dzero, dNaN), 0);
+  ieq (__aeabi_dcmplt (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmple (dzero, done), 1);
+  ieq (__aeabi_dcmple (done, dzero), 0);
+  ieq (__aeabi_dcmple (dzero, dzero), 1);
+  ieq (__aeabi_dcmple (dzero, dNaN), 0);
+  ieq (__aeabi_dcmple (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmpge (dzero, done), 0);
+  ieq (__aeabi_dcmpge (done, dzero), 1);
+  ieq (__aeabi_dcmpge (dzero, dzero), 1);
+  ieq (__aeabi_dcmpge (dzero, dNaN), 0);
+  ieq (__aeabi_dcmpge (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmpgt (dzero, done), 0);
+  ieq (__aeabi_dcmpgt (done, dzero), 1);
+  ieq (__aeabi_dcmplt (dzero, dzero), 0);
+  ieq (__aeabi_dcmpgt (dzero, dNaN), 0);
+  ieq (__aeabi_dcmpgt (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmpun (done, done), 0);
+  ieq (__aeabi_dcmpun (done, dzero), 0);
+  ieq (__aeabi_dcmpun (dNaN, dzero), 1);
+  ieq (__aeabi_dcmpun (dNaN, dNaN), 1);
+
+  /* Table 4.  Single-precision floating-point arithmetic.  */
+  feq (__aeabi_fadd (fzero, fone), fone);
+  feq (__aeabi_fadd (fone, fone), ftwo);
+  feq (__aeabi_fdiv (fminus_four, fminus_two), ftwo);
+  feq (__aeabi_fdiv (fminus_two, ftwo), fminus_one);
+  feq (__aeabi_fmul (ftwo, ftwo), ffour);
+  feq (__aeabi_fmul (fminus_one, fminus_two), ftwo);
+  feq (__aeabi_fneg (fminus_one), fone);
+  feq (__aeabi_fneg (ffour), fminus_four);
+  feq (__aeabi_frsub (fone, fzero), fminus_one);
+  feq (__aeabi_frsub (ftwo, fminus_two), fminus_four);
+  feq (__aeabi_fsub (fzero, fone), fminus_one);
+  feq (__aeabi_fsub (fminus_two, ftwo), fminus_four);
+
+  /* Table 5.  Single-precision floating-point comparisons.  */
+  ieq (__aeabi_fcmpeq (fone, fone), 1);
+  ieq (__aeabi_fcmpeq (fone, fzero), 0);
+  ieq (__aeabi_fcmpeq (fNaN, fzero), 0);
+  ieq (__aeabi_fcmpeq (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmplt (fzero, fone), 1);
+  ieq (__aeabi_fcmplt (fone, fzero), 0);
+  ieq (__aeabi_fcmplt (fzero, fzero), 0);
+  ieq (__aeabi_fcmplt (fzero, fNaN), 0);
+  ieq (__aeabi_fcmplt (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmple (fzero, fone), 1);
+  ieq (__aeabi_fcmple (fone, fzero), 0);
+  ieq (__aeabi_fcmple (fzero, fzero), 1);
+  ieq (__aeabi_fcmple (fzero, fNaN), 0);
+  ieq (__aeabi_fcmple (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmpge (fzero, fone), 0);
+  ieq (__aeabi_fcmpge (fone, fzero), 1);
+  ieq (__aeabi_fcmpge (fzero, fzero), 1);
+  ieq (__aeabi_fcmpge (fzero, fNaN), 0);
+  ieq (__aeabi_fcmpge (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmpgt (fzero, fone), 0);
+  ieq (__aeabi_fcmpgt (fone, fzero), 1);
+  ieq (__aeabi_fcmplt (fzero, fzero), 0);
+  ieq (__aeabi_fcmpgt (fzero, fNaN), 0);
+  ieq (__aeabi_fcmpgt (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmpun (fone, fone), 0);
+  ieq (__aeabi_fcmpun (fone, fzero), 0);
+  ieq (__aeabi_fcmpun (fNaN, fzero), 1);
+  ieq (__aeabi_fcmpun (fNaN, fNaN), 1);
+
+  /* Table 6.  Floating-point to integer conversions.  */
+  ieq (__aeabi_d2iz (dminus_one), -1);
+  ueq (__aeabi_d2uiz (done), 1);
+  leq (__aeabi_d2lz (dminus_two), -2LL);
+  uleq (__aeabi_d2ulz (dfour), 4LL);
+  ieq (__aeabi_f2iz (fminus_one), -1);
+  ueq (__aeabi_f2uiz (fone), 1);
+  leq (__aeabi_f2lz (fminus_two), -2LL);
+  uleq (__aeabi_f2ulz (ffour), 4LL);
+
+  /* Table 7.  Conversions between floating types.  */
+  feq (__aeabi_d2f (dtwo), ftwo);
+  deq (__aeabi_f2d (fminus_four), dminus_four);
+
+  /* Table 8.  Integer to floating-point conversions.  */
+  deq (__aeabi_i2d (-1), dminus_one);
+  deq (__aeabi_ui2d (2), dtwo);
+  deq (__aeabi_l2d (-1), dminus_one);
+  deq (__aeabi_ul2d (2ULL), dtwo);
+  feq (__aeabi_i2f (-1), fminus_one);
+  feq (__aeabi_ui2f (2), ftwo);
+  feq (__aeabi_l2f (-1), fminus_one);
+  feq (__aeabi_ul2f (2ULL), ftwo);
+
+  /* Table 9.  Long long functions.  */
+  leq (__aeabi_lmul (4LL, -1LL), -4LL);
+  leq (__aeabi_llsl (2LL, 1), 4LL);
+  leq (__aeabi_llsr (-1LL, 63), 1);
+  leq (__aeabi_lasr (-1LL, 63), -1);
+  ieq (__aeabi_lcmp (0LL, 1LL), -1);
+  ieq (__aeabi_lcmp (0LL, 0LL), 0);
+  ieq (__aeabi_lcmp (1LL, 0LL), 1);
+  ieq (__aeabi_ulcmp (0LL, 1LL), -1);
+  ieq (__aeabi_ulcmp (0LL, 0LL), 0);
+  ieq (__aeabi_ulcmp (1LL, 0LL), 1);
+}
diff --git a/gcc/testsuite/gcc.dg/dll-2.c b/gcc/testsuite/gcc.dg/dll-2.c
index 00c683a728ca..5c81f4e64a11 100644
--- a/gcc/testsuite/gcc.dg/dll-2.c
+++ b/gcc/testsuite/gcc.dg/dll-2.c
@@ -8,7 +8,7 @@
    In C, it's ok to redeclare a variable so this works for variables
    and functions.  In C++, it only works for functions.  */
 
-/* { dg-require-dll } */
+/* { dg-require-dll "" } */
 
 __declspec (dllimport) int foo1 ();
 __declspec (dllexport) int foo1 ();
diff --git a/gcc/testsuite/gcc.misc-tests/arm-isr.c b/gcc/testsuite/gcc.misc-tests/arm-isr.c
index f79e241633de..737f9ffb643b 100644
--- a/gcc/testsuite/gcc.misc-tests/arm-isr.c
+++ b/gcc/testsuite/gcc.misc-tests/arm-isr.c
@@ -1,3 +1,6 @@
+extern void abort ();
+extern void exit (int);
+
 #ifndef __thumb__
 /* There used to be a couple of bugs in the ARM's prologue and epilogue
    generation for ISR routines.  The wrong epilogue instruction would be
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 2c568b0473d1..da14057ff458 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,9 @@
+2004-08-09  Mark Mitchell  <mark@codesourcery.com>
+
+	* configure.ac (arm*-*-eabi*): New target.
+	(arm*-*-symbianelf*): Likewise.
+	* configure: Regenerated.
+
 2004-07-24  Bernardo Innocenti  <bernie@develer.com>
 
 	* internal.h (xnew, xcnew, xnewvec, xcnewvec, xobnew): Remove.
diff --git a/libcpp/configure b/libcpp/configure
index 18ae61b04532..f189f4d0ba09 100755
--- a/libcpp/configure
+++ b/libcpp/configure
@@ -969,7 +969,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -2428,7 +2428,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2486,7 +2487,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2602,7 +2604,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2656,7 +2659,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2701,7 +2705,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2745,7 +2750,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3074,7 +3080,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3135,7 +3142,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3449,7 +3457,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3619,7 +3628,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3696,7 +3706,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3888,7 +3899,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3948,7 +3960,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4018,7 +4031,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4091,7 +4105,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4156,7 +4171,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4220,7 +4236,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4283,7 +4300,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4345,7 +4363,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4385,7 +4404,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4441,7 +4461,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4481,7 +4502,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4545,7 +4567,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4576,8 +4599,10 @@ See \`config.log' for more details." >&2;}
 esac
 else
   if test "$cross_compiling" = yes; then
-  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
-echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -4689,7 +4714,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4751,7 +4777,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4791,7 +4818,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4847,7 +4875,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4887,7 +4916,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4951,7 +4981,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4982,8 +5013,10 @@ See \`config.log' for more details." >&2;}
 esac
 else
   if test "$cross_compiling" = yes; then
-  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
-echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -5137,7 +5170,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5201,7 +5235,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5270,7 +5305,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5339,7 +5375,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5408,7 +5445,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5477,7 +5515,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5546,7 +5585,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5615,7 +5655,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5687,7 +5728,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5768,7 +5810,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5909,7 +5952,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6045,7 +6089,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6207,7 +6252,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6335,7 +6381,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6976,7 +7023,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7026,7 +7074,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7116,7 +7165,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7180,6 +7230,8 @@ fi
 
 case $target in
 	alpha*-*-* | \
+	arm*-*-eabi* | \
+	arm*-*-symbianelf* | \
 	x86_64-*-* | \
 	ia64-*-* | \
 	hppa*64*-*-* | parisc*64*-*-* | \
@@ -8100,6 +8152,11 @@ esac
   *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
   esac
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -8138,12 +8195,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
 	 fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
diff --git a/libcpp/configure.ac b/libcpp/configure.ac
index ab6954490a57..e9d57dc762b3 100644
--- a/libcpp/configure.ac
+++ b/libcpp/configure.ac
@@ -65,6 +65,8 @@ fi
 m4_changequote(,)
 case $target in
 	alpha*-*-* | \
+	arm*-*-eabi* | \
+	arm*-*-symbianelf* | \
 	x86_64-*-* | \
 	ia64-*-* | \
 	hppa*64*-*-* | parisc*64*-*-* | \
-- 
GitLab