From 82a19768cb55aa06dc6aac858012cf40125a3d9f Mon Sep 17 00:00:00 2001 From: Andreas Tobler Date: Fri, 9 Jan 2015 15:06:02 +0100 Subject: [PATCH] configure.ac: Don't add ${libgcj} for arm*-*-freebsd*. 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. From-SVN: r219388 --- ChangeLog | 5 + configure | 3 + configure.ac | 3 + gcc/ChangeLog | 8 + gcc/config.gcc | 22 ++- gcc/config.host | 2 +- gcc/config/arm/arm.c | 2 +- gcc/config/arm/arm.h | 5 + gcc/config/arm/freebsd.h | 180 ++++++++++++++++++++++ gcc/ginclude/unwind-arm-common.h | 8 + libatomic/ChangeLog | 4 + libatomic/configure.tgt | 13 +- libgcc/ChangeLog | 9 ++ libgcc/config.host | 7 + libgcc/config/arm/freebsd-atomic.c | 224 ++++++++++++++++++++++++++++ libgcc/config/arm/t-freebsd | 9 ++ libgcc/config/arm/unwind-arm.h | 3 +- libstdc++-v3/ChangeLog | 4 + libstdc++-v3/configure.host | 3 + libstdc++-v3/libsupc++/unwind-cxx.h | 37 ++++- 20 files changed, 535 insertions(+), 16 deletions(-) create mode 100644 gcc/config/arm/freebsd.h create mode 100644 libgcc/config/arm/freebsd-atomic.c create mode 100644 libgcc/config/arm/t-freebsd diff --git a/ChangeLog b/ChangeLog index 901208751ed..c198ddd45a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-01-09 Andreas Tobler + + * configure.ac: Don't add ${libgcj} for arm*-*-freebsd*. + * configure: Regenerate. + 2015-01-08 Thomas Schwinge * Makefile.def (dependencies) : Depend on diff --git a/configure b/configure index a69a64d2486..33d2600145d 100755 --- a/configure +++ b/configure @@ -3433,6 +3433,9 @@ case "${target}" in alpha*-*-*vms*) noconfigdirs="$noconfigdirs ${libgcj}" ;; + arm*-*-freebsd*) + noconfigdirs="$noconfigdirs ${libgcj}" + ;; arm-wince-pe) noconfigdirs="$noconfigdirs ${libgcj}" ;; diff --git a/configure.ac b/configure.ac index 7c51079aa6a..acfae631928 100644 --- a/configure.ac +++ b/configure.ac @@ -783,6 +783,9 @@ case "${target}" in alpha*-*-*vms*) noconfigdirs="$noconfigdirs ${libgcj}" ;; + arm*-*-freebsd*) + noconfigdirs="$noconfigdirs ${libgcj}" + ;; arm-wince-pe) noconfigdirs="$noconfigdirs ${libgcj}" ;; diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cfb82f67558..f442a306524 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-01-09 Andreas Tobler + + * 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. + 2015-01-09 Sebastian Huber * config/rs6000/rtems.h (CPP_OS_RTEMS_SPEC): Define __PPC_CPU_E6500__ diff --git a/gcc/config.gcc b/gcc/config.gcc index 04026e38fb9..0dfc08fc0f1 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -259,7 +259,6 @@ case ${target} in arm*-wince-pe* \ | arm*-*-ecos-elf \ | arm*-*-elf \ - | arm*-*-freebsd* \ | arm*-*-linux* \ | arm*-*-uclinux* \ | i[34567]86-go32-* \ @@ -1010,6 +1009,27 @@ arm-wrs-vxworks) 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 + armv6*-*-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" diff --git a/gcc/config.host b/gcc/config.host index eda2d5dbac8..b0f5940c263 100644 --- a/gcc/config.host +++ b/gcc/config.host @@ -99,7 +99,7 @@ case ${host} in esac case ${host} in - arm*-*-linux*) + arm*-*-freebsd* | arm*-*-linux*) case ${target} in arm*-*-*) host_extra_gcc_objs="driver-arm.o" diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 8193bf1ce63..e437543fb4d 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2160,7 +2160,7 @@ arm_init_libfuncs (void) { /* For Linux, we have access to kernel support for atomic operations. */ if (arm_abi == ARM_ABI_AAPCS_LINUX) - init_sync_libfuncs (2 * UNITS_PER_WORD); + init_sync_libfuncs (MAX_SYNC_LIBFUNC_SIZE); /* There are no special library functions unless we are using the ARM BPABI. */ diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 8e3aeeb5a9a..9d60fcd1c93 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -766,6 +766,11 @@ extern int arm_arch_crc; #define PCC_BITFIELD_TYPE_MATTERS TARGET_AAPCS_BASED #endif +/* The maximum size of the sync library functions supported. */ +#ifndef MAX_SYNC_LIBFUNC_SIZE +#define MAX_SYNC_LIBFUNC_SIZE (2 * UNITS_PER_WORD); +#endif + /* Standard register usage. */ diff --git a/gcc/config/arm/freebsd.h b/gcc/config/arm/freebsd.h new file mode 100644 index 00000000000..040d7c13b0d --- /dev/null +++ b/gcc/config/arm/freebsd.h @@ -0,0 +1,180 @@ +/* Definitions of target machine for GNU compiler, FreeBSD/arm version. + Copyright (C) 2002-2015 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 + . */ + +#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 "unsigned 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 + +#define SUBTARGET_OVERRIDE_OPTIONS \ +do { \ + if (unaligned_access) \ + unaligned_access = 0; \ +} while (0) + +#undef MAX_SYNC_LIBFUNC_SIZE +#define MAX_SYNC_LIBFUNC_SIZE 4 /* UNITS_PER_WORD not defined yet. */ + +/* 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) + diff --git a/gcc/ginclude/unwind-arm-common.h b/gcc/ginclude/unwind-arm-common.h index 833786f01b3..52118c72967 100644 --- a/gcc/ginclude/unwind-arm-common.h +++ b/gcc/ginclude/unwind-arm-common.h @@ -82,7 +82,11 @@ extern "C" { struct _Unwind_Control_Block { +#ifdef __FreeBSD__ + unsigned exception_class __attribute__((__mode__(__DI__))); +#else char exception_class[8]; +#endif void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *); /* Unwinder cache, private fields for the unwinder's use */ struct @@ -181,7 +185,11 @@ extern "C" { /* Support functions for the PR. */ #define _Unwind_Exception _Unwind_Control_Block +#ifdef __FreeBSD__ + typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); +#else typedef char _Unwind_Exception_Class[8]; +#endif void * _Unwind_GetLanguageSpecificData (_Unwind_Context *); _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *); diff --git a/libatomic/ChangeLog b/libatomic/ChangeLog index 6490154127f..b0c72d3f952 100644 --- a/libatomic/ChangeLog +++ b/libatomic/ChangeLog @@ -1,3 +1,7 @@ +2015-01-09 Andreas Tobler + + * configure.tgt: Exclude arm*-*-freebsd* from try_ifunc. + 2015-01-05 Jakub Jelinek Update copyright years. diff --git a/libatomic/configure.tgt b/libatomic/configure.tgt index 4ab8e403fb9..3c1feddc356 100644 --- a/libatomic/configure.tgt +++ b/libatomic/configure.tgt @@ -37,10 +37,15 @@ case "${target_cpu}" in arm*) ARCH=arm - # ??? Detect when -march=armv7 is already enabled. - try_ifunc=yes - ;; - + case "${target}" in + arm*-*-freebsd*) + ;; + *) + # ??? Detect when -march=armv7 is already enabled. + try_ifunc=yes + ;; + esac + ;; sparc) case " ${CC} ${CFLAGS} " in *" -m64 "*) 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 + + * 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 * 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 +. */ + +#include + +#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; diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 50c74af9a5d..c6184fda434 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,7 @@ +2015-01-09 Andreas Tobler + + * configure.host: Add arm*-*-freebsd* port_specific_symbol_files. + 2015-01-09 Tim Shen PR libstdc++/64239 diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host index 6f7b09d51e9..82ddc524092 100644 --- a/libstdc++-v3/configure.host +++ b/libstdc++-v3/configure.host @@ -366,6 +366,9 @@ case "${host}" in ;; 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" ;; diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h index e6015964390..70f14b4d1b5 100644 --- a/libstdc++-v3/libsupc++/unwind-cxx.h +++ b/libstdc++-v3/libsupc++/unwind-cxx.h @@ -235,7 +235,7 @@ __get_dependent_exception_from_ue (_Unwind_Exception *exc) return reinterpret_cast<__cxa_dependent_exception *>(exc + 1) - 1; } -#ifdef __ARM_EABI_UNWINDER__ +#if defined (__ARM_EABI_UNWINDER__) && !defined (__FreeBSD__) static inline bool __is_gxx_exception_class(_Unwind_Exception_Class c) { @@ -309,13 +309,7 @@ __GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c) c[6] = 'R'; c[7] = '\0'; } - -static inline void* -__gxx_caught_object(_Unwind_Exception* eo) -{ - return (void*)eo->barrier_cache.bitpattern[0]; -} -#else // !__ARM_EABI_UNWINDER__ +#else // !__ARM_EABI_UNWINDER__ || __FreeBSD__ // This is the primary exception class we report -- "GNUCC++\0". const _Unwind_Exception_Class __gxx_primary_exception_class = ((((((((_Unwind_Exception_Class) 'G' @@ -339,6 +333,16 @@ const _Unwind_Exception_Class __gxx_dependent_exception_class << 8 | (_Unwind_Exception_Class) '+') << 8 | (_Unwind_Exception_Class) '\x01'); +const _Unwind_Exception_Class __gxx_forced_unwind_class += ((((((((_Unwind_Exception_Class) 'G' + << 8 | (_Unwind_Exception_Class) 'N') + << 8 | (_Unwind_Exception_Class) 'U') + << 8 | (_Unwind_Exception_Class) 'C') + << 8 | (_Unwind_Exception_Class) 'F') + << 8 | (_Unwind_Exception_Class) 'O') + << 8 | (_Unwind_Exception_Class) 'R') + << 8 | (_Unwind_Exception_Class) '\0'); + static inline bool __is_gxx_exception_class(_Unwind_Exception_Class c) { @@ -346,6 +350,12 @@ __is_gxx_exception_class(_Unwind_Exception_Class c) || c == __gxx_dependent_exception_class; } +static inline bool +__is_gxx_forced_unwind_class(_Unwind_Exception_Class c) +{ + return c == __gxx_forced_unwind_class; +} + // Only checks for primary or dependent, but not that it is a C++ exception at // all. static inline bool @@ -357,6 +367,17 @@ __is_dependent_exception(_Unwind_Exception_Class c) #define __GXX_INIT_PRIMARY_EXCEPTION_CLASS(c) c = __gxx_primary_exception_class #define __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(c) \ c = __gxx_dependent_exception_class +#define __GXX_INIT_FORCED_UNWIND_CLASS(c) c = __gxx_forced_unwind_class +#endif // __ARM_EABI_UNWINDER__ && !__FreeBSD__ + +#ifdef __ARM_EABI_UNWINDER__ +static inline void* +__gxx_caught_object(_Unwind_Exception* eo) +{ + return (void*)eo->barrier_cache.bitpattern[0]; +} + +#else // !__ARM_EABI_UNWINDER__ // GNU C++ personality routine, Version 0. extern "C" _Unwind_Reason_Code __gxx_personality_v0 -- 2.30.2