summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorandreast <andreast@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-09 14:06:02 +0000
committerandreast <andreast@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-09 14:06:02 +0000
commit275d0a7c13cfc8ac8eb740e3a733d6945404f90e (patch)
treeb3576f34396e29e95fbfc0175227cf0b88999832 /libgcc
parent9fda42775f0350363e72407ba0be0d152b23fbf4 (diff)
downloadgcc-275d0a7c13cfc8ac8eb740e3a733d6945404f90e.tar.gz
toplevel:
* configure.ac: Don't add ${libgcj} for arm*-*-freebsd*. * configure: Regenerate. gcc: * config.gcc (arm*-*-freebsd*): New configuration. * config/arm/freebsd.h: New file. * config.host: Add extra components for arm*-*-freebsd*. * config/arm/arm.h: Introduce MAX_SYNC_LIBFUNC_SIZE. * config/arm/arm.c (arm_init_libfuncs): Use MAX_SYNC_LIBFUNC_SIZE. libgcc: * 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. libatomic: * configure.tgt: Exclude arm*-*-freebsd* from try_ifunc. libstdc++-v3: * configure.host: Add arm*-*-freebsd* port_specific_symbol_files. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219388 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog9
-rw-r--r--libgcc/config.host7
-rw-r--r--libgcc/config/arm/freebsd-atomic.c224
-rw-r--r--libgcc/config/arm/t-freebsd9
-rw-r--r--libgcc/config/arm/unwind-arm.h3
5 files changed, 251 insertions, 1 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 241747f9562..84ebcc5c098 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,12 @@
+2015-01-09 Andreas Tobler <andreast@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.
+
2015-01-06 Eric Botcazou <ebotcazou@adacore.com>
* config.host: Add Visium support.
diff --git a/libgcc/config.host b/libgcc/config.host
index 667eb312a66..3065c8a06db 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -366,6 +366,13 @@ arm-wrs-vxworks)
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"
;;
diff --git a/libgcc/config/arm/freebsd-atomic.c b/libgcc/config/arm/freebsd-atomic.c
new file mode 100644
index 00000000000..a3a55e5d8ab
--- /dev/null
+++ b/libgcc/config/arm/freebsd-atomic.c
@@ -0,0 +1,224 @@
+/* FreeBSD specific atomic operations for ARM EABI.
+ Copyright (C) 2015 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
diff --git a/libgcc/config/arm/t-freebsd b/libgcc/config/arm/t-freebsd
new file mode 100644
index 00000000000..45b17865443
--- /dev/null
+++ b/libgcc/config/arm/t-freebsd
@@ -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
+
diff --git a/libgcc/config/arm/unwind-arm.h b/libgcc/config/arm/unwind-arm.h
index 21cee9a6fd7..f1f789c70e5 100644
--- a/libgcc/config/arm/unwind-arm.h
+++ b/libgcc/config/arm/unwind-arm.h
@@ -48,7 +48,8 @@ extern "C" {
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;