Hello all,

this is a patch which brings support for arm*-*-freebsd* to trunk.
The architectures supported are arm-*-*freebsd*, armv6-*-freebsd* and armv6hf-*-freebsd*.
armv6 stands for ARM_ARCH == 6, arm stands for ARM_ARCH < 6.

There is kernel development for armv8 aka. aarch64 ongoing but this is not covered here. This patch only covers 32-bit arm in a basic manner.

The patch is built and tested against armv6, armv6hf and arm. The former two tests (lots of) were done on a WANDBOARD-QUAD, the latter on a MARVELL board with 256MB Ram and 200MHz cpu.... (around 72h+ for a build and test.....)

Results for armv6hf are on the list. Only one entry but locally I ran several dozens runs...

Once if this patch is accepted a few test suite additions will follow.
(arm*-*-*eabi* -> arm_eabi)

The patch itself is also prepared for arm*eb*-*-freebsd*, but I could not test since I lack the HW.

I appreciate comments, questions and also an ack if this patch is ok for trunk.

TIA,

Andreas

toplevel:

2014-11-02  Andreas Tobler  <andre...@gcc.gnu.org>

        * configure.ac: Don't add ${libgcj} for arm*-*-freebsd*.
        * configure: Regenerate.

gcc:

2014-11-02  Andreas Tobler  <andre...@gcc.gnu.org>

        * config.gcc (arm*-*-freebsd*): New configuration.
        * config/arm/freebsd.h: New file.
        * config.host: A extras components for arm*-*-freebsd*.
        * config/arm/arm.c (arm_init_libfuncs): FreeBSD does not support 8 byte
        atomics for __ARM_ARCH__ < 6 yet.
        (arm_option_override): FreeBSD has not yet implemented unaligned access.

libgcc:

2014-11-02  Andreas Tobler  <andre...@gcc.gnu.org>

        * config.host (arm*-*-freebsd*): Add new configuration for
        arm*-*-freebsd*.
        * config/arm/freebsd-atomic.c: New file.
        * config/arm/t-freebsd: Likewise.
        * config/arm/unwind-arm.h: Add __FreeBSD__ to the list of 'PC-relative
        indirect' OS's.

libstdc++:

2014-11-02  Andreas Tobler  <andre...@gcc.gnu.org>

        * configure.host: Add arm*-*-freebsd* port_specific_symbol_files.

Index: configure.ac
===================================================================
--- configure.ac        (revision 217020)
+++ configure.ac        (working copy)
@@ -711,6 +711,9 @@
   alpha*-*-*vms*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
+  arm*-*-freebsd*)
+    noconfigdirs="$noconfigdirs ${libgcj}"
+    ;;
   arm-wince-pe)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c        (revision 217020)
+++ gcc/config/arm/arm.c        (working copy)
@@ -2202,7 +2202,11 @@
 {
   /* For Linux, we have access to kernel support for atomic operations.  */
   if (arm_abi == ARM_ABI_AAPCS_LINUX)
+#ifndef __FreeBSD__
     init_sync_libfuncs (2 * UNITS_PER_WORD);
+#else
+    init_sync_libfuncs (UNITS_PER_WORD);
+#endif
 
   /* There are no special library functions unless we are using the
      ARM BPABI.  */
@@ -3036,6 +3040,9 @@
       warning (0, "target CPU does not support unaligned accesses");
       unaligned_access = 0;
     }
+#ifdef __FreeBSD__
+      unaligned_access = 0;
+#endif
 
   if (TARGET_THUMB1 && flag_schedule_insns)
     {
Index: gcc/config/arm/freebsd.h
===================================================================
--- gcc/config/arm/freebsd.h    (revision 0)
+++ gcc/config/arm/freebsd.h    (working copy)
@@ -0,0 +1,170 @@
+/* Definitions of target machine for GNU compiler, FreeBSD/arm version.
+   Copyright (C) 2002-2014 Free Software Foundation, Inc.
+   Contributed by Wasabi Systems, Inc.
+
+   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 3, 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.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#undef  SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC FBSD_CPP_SPEC
+
+#undef  SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS                                  \
+  { "subtarget_extra_asm_spec",        SUBTARGET_EXTRA_ASM_SPEC },     \
+  { "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC },    \
+  { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
+
+#undef SUBTARGET_EXTRA_ASM_SPEC
+#define SUBTARGET_EXTRA_ASM_SPEC \
+  "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5} " TARGET_FIX_V4BX_SPEC " \
+  %{fpic|fpie:-k} %{fPIC|fPIE:-k}"
+
+#undef SUBTARGET_ASM_FLOAT_SPEC
+#ifdef TARGET_FREEBSD_ARM_HARD_FLOAT
+/* Default to full vfp if we build for arm*hf.  */
+#define SUBTARGET_ASM_FLOAT_SPEC "%{!mfpu=*:-mfpu=vfp}"
+#else
+#define SUBTARGET_ASM_FLOAT_SPEC "%{!mfpu=*:-mfpu=softvfp}"
+#endif
+
+#undef LINK_SPEC
+#define LINK_SPEC "                                                    \
+  %{p:%nconsider using `-pg' instead of `-p' with gprof (1) }          \
+  %{v:-V}                                                              \
+  %{assert*} %{R*} %{rpath*} %{defsym*}                                        
\
+  %{shared:-Bshareable %{h*} %{soname*}}                               \
+  %{!shared:                                                           \
+    %{!static:                                                         \
+      %{rdynamic:-export-dynamic}                                      \
+      %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }}      \
+    %{static:-Bstatic}}                                                        
\
+  %{!static:--hash-style=both --enable-new-dtags}                      \
+  %{symbolic:-Bsymbolic}                                               \
+  -X %{mbig-endian:-EB} %{mlittle-endian:-EL}"
+
+/* TARGET_BIG_ENDIAN_DEFAULT is set in
+   config.gcc for big endian configurations.  */
+#if TARGET_BIG_ENDIAN_DEFAULT
+#define TARGET_ENDIAN_DEFAULT    MASK_BIG_END
+#define TARGET_ENDIAN_OPTION     "mbig-endian"
+#define TARGET_LINKER_EMULATION  "armelfb_fbsd"
+#else
+#define TARGET_ENDIAN_DEFAULT    0
+#define TARGET_ENDIAN_OPTION     "mlittle-endian"
+#define TARGET_LINKER_EMULATION  "armelf_fbsd"
+#endif
+
+#undef SUBTARGET_EXTRA_LINK_SPEC
+#define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION " -p"
+
+#undef  TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS()               \
+  do                                           \
+    {                                          \
+       FBSD_TARGET_OS_CPP_BUILTINS ();         \
+       TARGET_BPABI_CPP_BUILTINS ();           \
+    }                                          \
+  while (false)
+
+/* We default to a soft-float ABI so that binaries can run on all
+   target hardware.  */
+#undef TARGET_DEFAULT_FLOAT_ABI
+#ifdef TARGET_FREEBSD_ARM_HARD_FLOAT
+#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_HARD
+#else
+#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
+#endif
+
+#undef ARM_DEFAULT_ABI
+
+/* AACPS_LINUX has access to kernel atomic ops while we don't.
+   But AACPS defaults to short_enums.  */
+#define ARM_DEFAULT_ABI ARM_ABI_AAPCS_LINUX
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_INTERWORK | TARGET_ENDIAN_DEFAULT)
+
+/* We do not have any MULTILIB_OPTIONS specified, so there are no
+   MULTILIB_DEFAULTS.  */
+#undef  MULTILIB_DEFAULTS
+
+/*  Use the AAPCS type for wchar_t, override the one from config/freebsd.h.  */
+#undef  WCHAR_TYPE
+#define WCHAR_TYPE (TARGET_AAPCS_BASED ? "unsigned int" : "long int")
+
+#undef  WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+#if defined (TARGET_FREEBSD_ARMv6)
+#undef  SUBTARGET_CPU_DEFAULT
+#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm1176jzs
+#else
+#undef  SUBTARGET_CPU_DEFAULT
+#define SUBTARGET_CPU_DEFAULT   TARGET_CPU_arm9
+#endif
+
+/* FreeBSD does its profiling differently to the Acorn compiler.  We
+   don't need a word following the mcount call; and to skip it
+   requires either an assembly stub or use of fomit-frame-pointer when
+   compiling the profiling functions.  Since we break Acorn CC
+   compatibility below a little more won't hurt.  */
+
+#undef ARM_FUNCTION_PROFILER
+#define ARM_FUNCTION_PROFILER(STREAM,LABELNO)          \
+{                                                      \
+  asm_fprintf (STREAM, "\tmov\t%Rip, %Rlr\n");         \
+  asm_fprintf (STREAM, "\tbl\t__mcount%s\n",           \
+              (TARGET_ARM && NEED_PLT_RELOC)           \
+              ? "(PLT)" : "");                         \
+}
+
+/* Clear the instruction cache from `BEG' to `END'.  This makes a
+   call to the ARM_SYNC_ICACHE architecture specific syscall.  */
+#define CLEAR_INSN_CACHE(BEG, END)                                     \
+do                                                                     \
+  {                                                                    \
+    extern int sysarch (int number, void *args);                       \
+    struct                                                             \
+      {                                                                        
\
+       unsigned int addr;                                              \
+       int          len;                                               \
+      } s;                                                             \
+    s.addr = (unsigned int) (BEG);                                     \
+    s.len = (END) - (BEG);                                             \
+    (void) sysarch (0, &s);                                            \
+  }                                                                    \
+while (0)
+
+/* This is how we tell the assembler that two symbols have the same value.  */
+#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
+  do                                      \
+    {                                     \
+     assemble_name (FILE, NAME1);         \
+     fputs (" = ", FILE);                 \
+     assemble_name (FILE, NAME2);         \
+     fputc ('\n', FILE);                  \
+    }                                     \
+  while (0)
+
+/* Add  .note.GNU-stack.  */
+#undef NEED_INDICATE_EXEC_STACK
+#define NEED_INDICATE_EXEC_STACK 1
+
+#define ARM_TARGET2_DWARF_FORMAT (DW_EH_PE_pcrel | DW_EH_PE_indirect)
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc      (revision 217020)
+++ gcc/config.gcc      (working copy)
@@ -259,7 +259,6 @@
    arm*-wince-pe*                      \
  | arm*-*-ecos-elf                     \
  | arm*-*-elf                          \
- | arm*-*-freebsd*                     \
  | arm*-*-linux*                       \
  | arm*-*-uclinux*                     \
  | i[34567]86-go32-*                   \
@@ -1000,6 +999,27 @@
        extra_options="${extra_options} arm/vxworks.opt"
        tmake_file="${tmake_file} arm/t-arm arm/t-vxworks"
        ;;
+arm*-*-freebsd*)                # ARM FreeBSD EABI
+       tm_file="dbxelf.h elfos.h ${fbsd_tm_file} arm/elf.h"
+       case $target in
+       arm*b-*-freebsd*)
+           tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+           ;;
+       esac
+       tmake_file="${tmake_file} arm/t-arm arm/t-bpabi"
+       tm_file="${tm_file} arm/bpabi.h arm/freebsd.h arm/aout.h arm/arm.h"
+       case $target in
+       armv[67]*-*-freebsd*)
+           tm_defines="${tm_defines} TARGET_FREEBSD_ARMv6=1"
+           ;;
+       esac
+       case $target in
+       arm*hf-*-freebsd*)
+           tm_defines="${tm_defines} TARGET_FREEBSD_ARM_HARD_FLOAT=1"
+           ;;
+       esac
+       with_tls=${with_tls:-gnu}
+       ;;
 arm*-*-netbsdelf*)
        tm_file="dbxelf.h elfos.h netbsd.h netbsd-elf.h arm/elf.h arm/aout.h 
${tm_file} arm/netbsd-elf.h"
        extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
Index: gcc/config.host
===================================================================
--- gcc/config.host     (revision 217020)
+++ gcc/config.host     (working copy)
@@ -99,7 +99,7 @@
 esac
 
 case ${host} in
-  arm*-*-linux*)
+  arm*-*-freebsd* | arm*-*-linux*)
     case ${target} in
       arm*-*-*)
        host_extra_gcc_objs="driver-arm.o"
Index: libgcc/config/arm/freebsd-atomic.c
===================================================================
--- libgcc/config/arm/freebsd-atomic.c  (revision 0)
+++ libgcc/config/arm/freebsd-atomic.c  (working copy)
@@ -0,0 +1,224 @@
+/* FreeBSD specific atomic operations for ARM EABI.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include <sys/types.h>
+
+#define HIDDEN __attribute__ ((visibility ("hidden")))
+
+#define ARM_VECTORS_HIGH 0xffff0000U
+#define ARM_TP_ADDRESS   (ARM_VECTORS_HIGH + 0x1000)
+#define ARM_RAS_START    (ARM_TP_ADDRESS + 4)
+
+void HIDDEN
+__sync_synchronize (void)
+{
+#if defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__)       \
+    || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6T2__)  \
+    || defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6ZK__)  \
+    || defined (__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__)
+#if defined (__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__)
+    __asm __volatile ("dmb" : : : "memory");
+#else
+    __asm __volatile ("mcr p15, 0, r0, c7, c10, 5" : : : "memory");
+#endif
+#else
+    __asm __volatile ("nop" : : : "memory");
+#endif
+}
+
+#if defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__)        \
+    || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6T2__)   \
+    || defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6ZK__)   \
+    || defined (__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__)
+
+/* These systems should be supported by the compiler.  */
+
+#else /* __ARM_ARCH_5__  */
+
+#define        SYNC_LOCK_TEST_AND_SET_N(N, TYPE, LDR, STR)                     
\
+TYPE HIDDEN                                                                    
\
+__sync_lock_test_and_set_##N (TYPE *mem, TYPE val)                     \
+{                                                                      \
+        unsigned int old, temp, ras_start;                              \
+                                                                        \
+        ras_start = ARM_RAS_START;                                     \
+        __asm volatile (                                               \
+                /* Set up Restartable Atomic Sequence.  */             \
+                "1:"                                                   \
+                "\tadr   %2, 1b\n"                                     \
+                "\tstr   %2, [%5]\n"                                   \
+                "\tadr   %2, 2f\n"                                     \
+                "\tstr   %2, [%5, #4]\n"                               \
+                                                                        \
+                "\t"LDR" %0, %4\n"     /* Load old value.  */          \
+                "\t"STR" %3, %1\n"     /* Store new value.  */         \
+                                                                        \
+                /* Tear down Restartable Atomic Sequence.  */          \
+                "2:"                                                   \
+                "\tmov   %2, #0x00000000\n"                            \
+                "\tstr   %2, [%5]\n"                                   \
+                "\tmov   %2, #0xffffffff\n"                            \
+                "\tstr   %2, [%5, #4]\n"                               \
+                : "=&r" (old), "=m" (*mem), "=&r" (temp)               \
+                : "r" (val), "m" (*mem), "r" (ras_start));             \
+        return (old);                                                  \
+}
+
+#define SYNC_LOCK_RELEASE_N(N, TYPE)                                   \
+void HIDDEN                                                            \
+__sync_lock_release_##N (TYPE *ptr)                                    \
+{                                                                      \
+    /* All writes before this point must be seen before we release     \
+       the lock itself.  */                                            \
+    __sync_synchronize ();                                                     
\
+    *ptr = 0;                                                          \
+}
+
+#define        SYNC_VAL_CAS_N(N, TYPE, LDR, STREQ)                             
\
+TYPE HIDDEN                                                                    
\
+__sync_val_compare_and_swap_##N (TYPE *mem, TYPE expected,             \
+    TYPE desired)                                                      \
+{                                                                      \
+        unsigned int old, temp, ras_start;                              \
+                                                                        \
+        ras_start = ARM_RAS_START;                                     \
+        __asm volatile (                                               \
+                /* Set up Restartable Atomic Sequence.  */             \
+                "1:"                                                   \
+                "\tadr   %2, 1b\n"                                     \
+                "\tstr   %2, [%6]\n"                                   \
+                "\tadr   %2, 2f\n"                                     \
+                "\tstr   %2, [%6, #4]\n"                               \
+                                                                        \
+                "\t"LDR" %0, %5\n"     /* Load old value.  */          \
+                "\tcmp   %0, %3\n"     /* Compare to expected value.  */\
+                "\t"STREQ" %4, %1\n"   /* Store new value.  */         \
+                                                                        \
+                /* Tear down Restartable Atomic Sequence.  */          \
+                "2:"                                                   \
+                "\tmov   %2, #0x00000000\n"                            \
+                "\tstr   %2, [%6]\n"                                   \
+                "\tmov   %2, #0xffffffff\n"                            \
+                "\tstr   %2, [%6, #4]\n"                               \
+                : "=&r" (old), "=m" (*mem), "=&r" (temp)               \
+                : "r" (expected), "r" (desired), "m" (*mem),           \
+                  "r" (ras_start));                                    \
+        return (old);                                                  \
+}
+
+typedef unsigned char bool;
+
+#define SYNC_BOOL_CAS_N(N, TYPE)                                        \
+bool HIDDEN                                                            \
+__sync_bool_compare_and_swap_##N (TYPE *ptr, TYPE oldval,              \
+                                  TYPE newval)                          \
+{                                                                      \
+    TYPE actual_oldval                                                 \
+      = __sync_val_compare_and_swap_##N (ptr, oldval, newval);          \
+    return (oldval == actual_oldval);                                  \
+}
+
+#define        SYNC_FETCH_AND_OP_N(N, TYPE, LDR, STR, NAME, OP)                
\
+TYPE HIDDEN                                                            \
+__sync_fetch_and_##NAME##_##N (TYPE *mem, TYPE val)                    \
+{                                                                      \
+        unsigned int old, temp, ras_start;                              \
+                                                                        \
+        ras_start = ARM_RAS_START;                                     \
+        __asm volatile (                                               \
+                /* Set up Restartable Atomic Sequence.  */             \
+                "1:"                                                   \
+                "\tadr   %2, 1b\n"                                     \
+                "\tstr   %2, [%5]\n"                                   \
+                "\tadr   %2, 2f\n"                                     \
+                "\tstr   %2, [%5, #4]\n"                               \
+                                                                        \
+                "\t"LDR" %0, %4\n"     /* Load old value.  */          \
+                "\t"OP"  %2, %0, %3\n" /* Calculate new value.  */     \
+                "\t"STR" %2, %1\n"     /* Store new value.  */         \
+                                                                        \
+                /* Tear down Restartable Atomic Sequence.  */          \
+                "2:"                                                   \
+                "\tmov   %2, #0x00000000\n"                            \
+                "\tstr   %2, [%5]\n"                                   \
+                "\tmov   %2, #0xffffffff\n"                            \
+                "\tstr   %2, [%5, #4]\n"                               \
+                : "=&r" (old), "=m" (*mem), "=&r" (temp)               \
+                : "r" (val), "m" (*mem), "r" (ras_start));             \
+        return (old);                                                  \
+}
+
+#define        SYNC_OP_AND_FETCH_N(N, TYPE, LDR, STR, NAME, OP)                
\
+TYPE HIDDEN                                                            \
+__sync_##NAME##_and_fetch_##N (TYPE *mem, TYPE val)                    \
+{                                                                      \
+        unsigned int old, temp, ras_start;                              \
+                                                                        \
+        ras_start = ARM_RAS_START;                                     \
+        __asm volatile (                                               \
+                /* Set up Restartable Atomic Sequence.  */             \
+                "1:"                                                   \
+                "\tadr   %2, 1b\n"                                     \
+                "\tstr   %2, [%5]\n"                                   \
+                "\tadr   %2, 2f\n"                                     \
+                "\tstr   %2, [%5, #4]\n"                               \
+                                                                        \
+                "\t"LDR" %0, %4\n"     /* Load old value.  */          \
+                "\t"OP"  %2, %0, %3\n" /* Calculate new value.  */     \
+                "\t"STR" %2, %1\n"     /* Store new value.  */         \
+                                                                        \
+                /* Tear down Restartable Atomic Sequence.  */          \
+                "2:"                                                   \
+                "\tmov   %2, #0x00000000\n"                            \
+                "\tstr   %2, [%5]\n"                                   \
+                "\tmov   %2, #0xffffffff\n"                            \
+                "\tstr   %2, [%5, #4]\n"                               \
+                : "=&r" (old), "=m" (*mem), "=&r" (temp)               \
+                : "r" (val), "m" (*mem), "r" (ras_start));             \
+        return (old);                                                  \
+}
+
+#define        EMIT_ALL_OPS_N(N, TYPE, LDR, STR, STREQ)                        
\
+SYNC_LOCK_TEST_AND_SET_N (N, TYPE, LDR, STR)                           \
+SYNC_LOCK_RELEASE_N (N, TYPE)                                           \
+SYNC_VAL_CAS_N (N, TYPE, LDR, STREQ)                                   \
+SYNC_BOOL_CAS_N (N, TYPE)                                               \
+SYNC_FETCH_AND_OP_N (N, TYPE, LDR, STR, add, "add")                    \
+SYNC_FETCH_AND_OP_N (N, TYPE, LDR, STR, and, "and")                    \
+SYNC_FETCH_AND_OP_N (N, TYPE, LDR, STR, or, "orr")                     \
+SYNC_FETCH_AND_OP_N (N, TYPE, LDR, STR, sub, "sub")                    \
+SYNC_FETCH_AND_OP_N (N, TYPE, LDR, STR, xor, "eor")                     \
+SYNC_OP_AND_FETCH_N (N, TYPE, LDR, STR, add, "add")                    \
+SYNC_OP_AND_FETCH_N (N, TYPE, LDR, STR, and, "and")                    \
+SYNC_OP_AND_FETCH_N (N, TYPE, LDR, STR, or, "orr")                     \
+SYNC_OP_AND_FETCH_N (N, TYPE, LDR, STR, sub, "sub")                    \
+SYNC_OP_AND_FETCH_N (N, TYPE, LDR, STR, xor, "eor")
+
+
+
+EMIT_ALL_OPS_N (1, unsigned char, "ldrb", "strb", "streqb")
+EMIT_ALL_OPS_N (2, unsigned short, "ldrh", "strh", "streqh")
+EMIT_ALL_OPS_N (4, unsigned int, "ldr", "str", "streq")
+
+#endif
Index: libgcc/config/arm/t-freebsd
===================================================================
--- libgcc/config/arm/t-freebsd (revision 0)
+++ libgcc/config/arm/t-freebsd (working copy)
@@ -0,0 +1,9 @@
+# Just for these, we omit the frame pointer since it makes such a big
+# difference.  It is then pointless adding debugging.
+HOST_LIBGCC2_CFLAGS += -fomit-frame-pointer
+
+LIB2ADD_ST += $(srcdir)/config/arm/freebsd-atomic.c
+
+# Use a version of div0 which raises SIGFPE.
+LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx
+
Index: libgcc/config/arm/unwind-arm.h
===================================================================
--- libgcc/config/arm/unwind-arm.h      (revision 217020)
+++ libgcc/config/arm/unwind-arm.h      (working copy)
@@ -48,7 +48,8 @@
       if (!tmp)
        return 0;
 
-#if (defined(linux) && !defined(__uClinux__)) || defined(__NetBSD__)
+#if (defined(linux) && !defined(__uClinux__)) || defined(__NetBSD__) \
+    || defined(__FreeBSD__)
       /* Pc-relative indirect.  */
 #define _GLIBCXX_OVERRIDE_TTYPE_ENCODING (DW_EH_PE_pcrel | DW_EH_PE_indirect)
       tmp += ptr;
Index: libgcc/config.host
===================================================================
--- libgcc/config.host  (revision 217020)
+++ libgcc/config.host  (working copy)
@@ -366,6 +366,13 @@
        tmake_file="$tmake_file arm/t-arm arm/t-elf t-softfp-sfdf t-softfp-excl 
arm/t-softfp t-softfp"
        extra_parts="$extra_parts crti.o crtn.o"
        ;;
+arm*-*-freebsd*)                # ARM FreeBSD EABI
+       tmake_file="${tmake_file} arm/t-arm t-fixedpoint-gnu-prefix arm/t-elf"
+       tmake_file="${tmake_file} arm/t-bpabi arm/t-freebsd t-slibgcc-libgcc"
+       tm_file="${tm_file} arm/bpabi-lib.h"
+       unwind_header=config/arm/unwind-arm.h
+       tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl arm/t-softfp 
t-softfp"
+       ;;
 arm*-*-netbsdelf*)
        tmake_file="$tmake_file arm/t-arm arm/t-netbsd t-slibgcc-gld-nover"
        ;;
Index: libstdc++-v3/configure.host
===================================================================
--- libstdc++-v3/configure.host (revision 217020)
+++ libstdc++-v3/configure.host (working copy)
@@ -366,6 +366,9 @@
        ;;
     esac
     ;;
+  arm*-*-freebsd*)
+     
port_specific_symbol_files="\$(srcdir)/../config/os/gnu-linux/arm-eabi-extra.ver"
+     ;;
   powerpc*-*-darwin*)
     
port_specific_symbol_files="\$(srcdir)/../config/os/bsd/darwin/ppc-extra.ver"
     ;;

Reply via email to