summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog139
-rw-r--r--libgcc/Makefile.in8
-rw-r--r--libgcc/config.host51
-rw-r--r--libgcc/config/alpha/qrnnd.S12
-rw-r--r--libgcc/config/arm/lib1funcs.S70
-rw-r--r--libgcc/config/avr/lib1funcs.S469
-rw-r--r--libgcc/config/avr/t-avr6
-rw-r--r--libgcc/config/darwin-crt-tm.c77
-rw-r--r--libgcc/config/i386/t-darwin642
-rw-r--r--libgcc/config/m68k/linux-atomic.c211
-rw-r--r--libgcc/config/m68k/t-linux1
-rw-r--r--libgcc/config/rs6000/t-ppccomm21
-rw-r--r--libgcc/config/rs6000/t-ppccomm-ldbl1
-rw-r--r--libgcc/config/rs6000/t-savresfgpr21
-rw-r--r--libgcc/config/sh/t-netbsd2
-rw-r--r--libgcc/config/t-darwin6
-rw-r--r--libgcc/crtstuff.c104
-rw-r--r--libgcc/generic-morestack.c76
-rw-r--r--libgcc/libgcc-std.ver.in2
-rw-r--r--libgcc/static-object.mk7
20 files changed, 1216 insertions, 70 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index c10667bd428..f146181da9c 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,142 @@
+2011-11-28 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR other/51022
+ * config/rs6000/t-savresfgpr: New file.
+ * config/rs6000/t-ppccomm (LIB2ADD_ST): Remove all but
+ $(srcdir)/config/rs6000/eabi.S.
+ * config/rs6000/t-ppccomm-ldbl: Remove.
+ * config.host (powerpc-*-freebsd*): Add rs6000/t-savresfgpr to
+ tmake_file.
+ (powerpc-*-eabispe*): Likewise.
+ (powerpc-*-eabi*): Likewise.
+ (powerpc-*-linux*, powerpc64-*-linux*): Likewise.
+ (powerpc-wrs-vxworks, powerpc-wrs-vxworksae): Add rs6000/t-ppccomm
+ to tmake_file, remove rs6000/t-ppccomm-ldbl.
+ (powerpc-*-eabisimaltivec*): Remove rs6000/t-ppccomm-ldbl from
+ tmake_file.
+ (powerpc-*-eabisim*): Likewise.
+ (powerpc-*-elf*): Likewise.
+ (powerpc-*-eabialtivec*): Likewise.
+ (powerpc-xilinx-eabi*): Likewise.
+ (powerpc-*-rtems*): Likewise.
+ (powerpcle-*-elf*): Likewise.
+ (powerpcle-*-eabisim*): Likewise.
+ (powerpcle-*-eabi*): Likewise.
+
+2011-11-27 Ian Lance Taylor <iant@google.com>
+
+ * generic-morestack.c (__splitstack_find): Check for NULL old
+ stack value.
+ (__splitstack_resetcontext): New function.
+ (__splitstack_releasecontext): New function.
+ * libgcc-std.ver.in: Add new functions to GCC_4.7.0.
+
+2011-11-27 Iain Sandoe <iains@gcc.gnu.org>
+
+ * config/darwin-crt-tm.c: Correct comments, use correct licence.
+
+2011-11-27 Iain Sandoe <iains@gcc.gnu.org>
+
+ * config/darwin-crt-tm.c: Remove dummy _ITM_ functions.
+
+2011-11-26 Richard Henderson <rth@redhat.com>
+
+ * config/m68k/linux-atomic.c: New file.
+ * config/m68k/t-linux: New file.
+ * config.host (m68k-uclinux, m68k-linux): Use it.
+
+2011-11-26 Richard Henderson <rth@redhat.com>
+
+ * crtstuff.c (__TMC_LIST__): Mark used not unused.
+ (__TMC_END__): Only declare if hidden is available; in the definition,
+ if hidden is unavailable add a null record.
+ (deregister_tm_clones, register_tm_clones): New.
+ (__do_global_dtors_aux, frame_dummy): Use them.
+ (__do_global_dtors, __do_global_ctors_1): Likewise.
+
+2011-11-22 Iain Sandoe <iains@gcc.gnu.org>
+
+ * config/darwin-crt-tm.c: New file.
+ * config.host (darwin): Build crttms.o crttme.o to provide
+ startup and shutdown for tm clones.
+ * config/t-darwin (crttms.o): New build rule.
+ (crttme.o): Likewise.
+
+2011-11-21 Hans-Peter Nilsson <hp@axis.com>
+
+ * Makefile.in ($(srcdir)/emutls.c): Explain why it's in LIB2ADDEH
+ et al.
+
+2011-11-21 Richard Henderson <rth@redhat.com>
+
+ * crtstuff.c (USE_TM_CLONE_REGISTRY): Default to 1 on ELF.
+ (__TMC_LIST__, __TMC_END__): New.
+ (__do_global_dtors_aux): Call _ITM_deregisterTMCloneTable.
+ (__do_global_dtors): Likewise.
+ (frame_dummy): Call _ITM_registerTMCloneTable.
+ (__do_global_ctors_1): Likewise.
+
+2011-11-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * config.host (iq2000*-*-elf*): Add iq2000/t-iq2000 to tmake_file.
+ (powerpc-*-netbsd*): Add rs6000/t-netbsd to tmake_file.
+ (powerpc-wrs-vxworks, powerpc-wrs-vxworksae): Add to tmake_file.
+ (powerpc-*-lynxos*): Add rs6000/t-lynx to tmake_file.
+ * config/i386/t-darwin64: Remove.
+ * config/sh/t-netbsd (LIB2ADD): Remove.
+
+2011-11-21 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/49313
+ * config/avr/t-avr (LIB2FUNCS_EXCLUDE): Add _moddi3, _umoddi3.
+ (LIB1ASMFUNCS): Add _divdi3, _udivdi3, _udivmod64, _negdi2.
+ * config/avr/lib1funcs.S (wmov): New assembler macro.
+ (__umoddi3, __udivdi3, __udivdi3_umoddi3): New functions.
+ (__moddi3, __divdi3, __divdi3_moddi3): New functions.
+ (__udivmod64): New function.
+ (__negdi2): New function.
+
+2011-11-21 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * config.host (*-*-freebsd[12], *-*-freebsd[12].*,
+ *-*-freebsd*aout*): Remove.
+
+2011-11-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * static-object.mk (c_flags-$o): Save c_flags.
+ ($(base)$(objext)): Use it.
+
+2011-11-18 Steve Ellcey <sje@cup.hp.com>
+
+ * Makefile.in (c_flags): Set to -fno-exceptions to build libunwind.
+
+2011-11-18 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/49868
+ * config/avr/t-avr (LIB1ASMFUNCS): Add _xload_2 _xload_3 _xload_4.
+ * config/avr/lib1funcs.S (__xload_2, __xload_3, __xload_4):
+ New functions.
+
+2011-11-16 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * config/arm/lib1funcs.asm (udivsi3): Add support for divide
+ functions.
+ (aeabi_uidivmod): Likewise.
+ (umodsi3): Likewise.
+ (divsi3): Likewise.
+ (aeabi_idivmod): Likewise.
+ (modsi3): Likewise.
+
+2011-11-16 Tristan Gingold <gingold@adacore.com>
+
+ * config/alpha/qrnnd.S: Use specific pseudos for VMS.
+
+2011-11-15 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/49868
+ * config/avr/t-avr (LIB1ASMFUNCS): Add _load_3, _load_4.
+ * config/avr/lib1funcs.S (__load_3, __load_4, __xload_2): New functions.
+
2011-11-13 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* config.host (hppa*64*-*-hpux11*): Remove pa/t-stublib64 from
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 3a8509d118c..23b72b92475 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -394,6 +394,9 @@ endif
LIB2ADD += enable-execute-stack.c
+# While emutls.c has nothing to do with EH, it is in LIB2ADDEH*
+# instead of LIB2ADD because that's the way to be sure on some targets
+# (e.g. *-*-darwin*) only one copy of it is linked.
LIB2ADDEH += $(srcdir)/emutls.c
LIB2ADDEHSTATIC += $(srcdir)/emutls.c
LIB2ADDEHSHARED += $(srcdir)/emutls.c
@@ -827,9 +830,10 @@ include $(iterator)
endif
-# Build LIBUNWIND.
+# Build LIBUNWIND. Use -fno-exceptions so that the unwind library does
+# not generate calls to __gcc_personality_v0.
-c_flags := -fexceptions
+c_flags := -fno-exceptions
libunwind-objects += $(addsuffix $(objext),$(basename $(notdir $(LIBUNWIND))))
diff --git a/libgcc/config.host b/libgcc/config.host
index 342d60c6be7..a9fb9ad8d08 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -170,16 +170,7 @@ case ${host} in
*-*-darwin*)
asm_hidden_op=.private_extern
tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-libgcc-pic t-slibgcc-darwin"
- extra_parts=crt3.o
- ;;
-*-*-freebsd[12] | *-*-freebsd[12].* | *-*-freebsd*aout*)
- # This is the place-holder for the generic a.out configuration
- # of FreeBSD. No actual configuration resides here since
- # there was only ever a bare-bones ix86 configuration for
- # a.out and it exists solely in the machine-specific section.
- # This place-holder must exist to avoid dropping into
- # the generic ELF configuration of FreeBSD (i.e. it must be
- # ordered before that section).
+ extra_parts="crt3.o crttms.o crttme.o"
;;
*-*-freebsd*)
# This is the generic ELF configuration of FreeBSD. Later
@@ -672,7 +663,7 @@ ia64-hp-*vms*)
md_unwind_header=ia64/vms-unwind.h
;;
iq2000*-*-elf*)
- tmake_file=t-fdpbit
+ tmake_file="iq2000/t-iq2000 t-fdpbit"
# Don't use default.
extra_parts=
;;
@@ -710,14 +701,14 @@ m68k*-*-netbsdelf*)
;;
m68k*-*-openbsd*)
;;
-m68k-*-uclinux*) # Motorola m68k/ColdFire running uClinux with uClibc
- tmake_file="$tmake_file m68k/t-floatlib"
+m68k-*-uclinux*) # Motorola m68k/ColdFire running uClinux with uClibc
+ tmake_file="$tmake_file m68k/t-floatlib m68k/t-linux"
md_unwind_header=m68k/linux-unwind.h
;;
m68k-*-linux*) # Motorola m68k's running GNU/Linux
# with ELF format using glibc 2
# aka the GNU/Linux C library 6.
- tmake_file="$tmake_file m68k/t-floatlib"
+ tmake_file="$tmake_file m68k/t-floatlib m68k/t-linux"
# If not configured with --enable-sjlj-exceptions, bump the
# libgcc version number.
if test x$enable_sjlj_exceptions != xyes; then
@@ -852,65 +843,65 @@ powerpc64-*-darwin*)
extra_parts="$extra_parts crt2.o"
;;
powerpc-*-freebsd*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff rs6000/t-freebsd t-softfp-sfdf t-softfp-excl t-softfp t-slibgcc-libgcc"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff rs6000/t-freebsd t-softfp-sfdf t-softfp-excl t-softfp t-slibgcc-libgcc"
extra_parts="$extra_parts crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpc-*-netbsd*)
- tmake_file="$tmake_file rs6000/t-crtstuff"
+ tmake_file="$tmake_file rs6000/t-netbsd rs6000/t-crtstuff"
;;
powerpc-*-eabispe*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic"
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpc-*-eabisimaltivec*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ppccomm-ldbl rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpc-*-eabisim*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ppccomm-ldbl rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpc-*-elf*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ppccomm-ldbl rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpc-*-eabialtivec*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ppccomm-ldbl rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpc-xilinx-eabi*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ppccomm-ldbl rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpc-*-eabi*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpc-*-rtems*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ppccomm-ldbl rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpc-*-linux* | powerpc64-*-linux*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff rs6000/t-linux t-softfp-sfdf t-softfp-excl t-dfprules rs6000/t-ppc64-fp t-softfp t-slibgcc-libgcc"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff rs6000/t-linux t-softfp-sfdf t-softfp-excl t-dfprules rs6000/t-ppc64-fp t-softfp t-slibgcc-libgcc"
extra_parts="$extra_parts ecrti.o ecrtn.o ncrti.o ncrtn.o"
md_unwind_header=rs6000/linux-unwind.h
;;
powerpc-wrs-vxworks|powerpc-wrs-vxworksae)
- tmake_file="rs6000/t-ppccomm-ldbl t-fdpbit"
+ tmake_file="$tmake_file rs6000/t-ppccomm t-fdpbit"
;;
powerpc-*-lynxos*)
- tmake_file="$tmake_file t-fdpbit"
+ tmake_file="$tmake_file rs6000/t-lynx t-fdpbit"
;;
powerpcle-*-elf*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ppccomm-ldbl rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpcle-*-eabisim*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ppccomm-ldbl rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
powerpcle-*-eabi*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ppccomm-ldbl rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
diff --git a/libgcc/config/alpha/qrnnd.S b/libgcc/config/alpha/qrnnd.S
index 51b13bce6ad..794cf65b486 100644
--- a/libgcc/config/alpha/qrnnd.S
+++ b/libgcc/config/alpha/qrnnd.S
@@ -33,9 +33,15 @@
.globl __udiv_qrnnd
.ent __udiv_qrnnd
+#ifdef __VMS__
+__udiv_qrnnd..en:
+ .frame $29,0,$26,0
+ .prologue
+#else
__udiv_qrnnd:
.frame $30,0,$26,0
.prologue 0
+#endif
#define cnt $2
#define tmp $3
@@ -160,4 +166,10 @@ $Odd:
bis $31,n0,$0
ret $31,($26),1
+#ifdef __VMS__
+ .link
+ .align 3
+__udiv_qrnnd:
+ .pdesc __udiv_qrnnd..en,null
+#endif
.end __udiv_qrnnd
diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S
index 2e76c01df4b..094d79afad6 100644
--- a/libgcc/config/arm/lib1funcs.S
+++ b/libgcc/config/arm/lib1funcs.S
@@ -951,6 +951,17 @@ LSYM(udivsi3_skip_div0_test):
pop { work }
RET
+#elif defined(__ARM_ARCH_EXT_IDIV__)
+
+ ARM_FUNC_START udivsi3
+ ARM_FUNC_ALIAS aeabi_uidiv udivsi3
+
+ cmp r1, #0
+ beq LSYM(Ldiv0)
+
+ udiv r0, r0, r1
+ RET
+
#else /* ARM version/Thumb-2. */
ARM_FUNC_START udivsi3
@@ -997,6 +1008,14 @@ FUNC_START aeabi_uidivmod
mul r2, r0
sub r1, r1, r2
bx r3
+#elif defined(__ARM_ARCH_EXT_IDIV__)
+ARM_FUNC_START aeabi_uidivmod
+ cmp r1, #0
+ beq LSYM(Ldiv0)
+ mov r2, r0
+ udiv r0, r0, r1
+ mls r1, r0, r1, r2
+ RET
#else
ARM_FUNC_START aeabi_uidivmod
cmp r1, #0
@@ -1014,9 +1033,19 @@ ARM_FUNC_START aeabi_uidivmod
/* ------------------------------------------------------------------------ */
#ifdef L_umodsi3
- FUNC_START umodsi3
+#ifdef __ARM_ARCH_EXT_IDIV__
-#ifdef __thumb__
+ ARM_FUNC_START umodsi3
+
+ cmp r1, #0
+ beq LSYM(Ldiv0)
+ udiv r2, r0, r1
+ mls r0, r1, r2, r0
+ RET
+
+#elif defined(__thumb__)
+
+ FUNC_START umodsi3
cmp divisor, #0
beq LSYM(Ldiv0)
@@ -1035,6 +1064,8 @@ LSYM(Lover10):
#else /* ARM version. */
+ FUNC_START umodsi3
+
subs r2, r1, #1 @ compare divisor with 1
bcc LSYM(Ldiv0)
cmpne r0, r1 @ compare dividend with divisor
@@ -1091,6 +1122,16 @@ LSYM(Lover12):
pop { work }
RET
+#elif defined(__ARM_ARCH_EXT_IDIV__)
+
+ ARM_FUNC_START divsi3
+ ARM_FUNC_ALIAS aeabi_idiv divsi3
+
+ cmp r1, #0
+ beq LSYM(Ldiv0)
+ sdiv r0, r0, r1
+ RET
+
#else /* ARM/Thumb-2 version. */
ARM_FUNC_START divsi3
@@ -1153,6 +1194,14 @@ FUNC_START aeabi_idivmod
mul r2, r0
sub r1, r1, r2
bx r3
+#elif defined(__ARM_ARCH_EXT_IDIV__)
+ARM_FUNC_START aeabi_idivmod
+ cmp r1, #0
+ beq LSYM(Ldiv0)
+ mov r2, r0
+ sdiv r0, r0, r1
+ mls r1, r0, r1, r2
+ RET
#else
ARM_FUNC_START aeabi_idivmod
cmp r1, #0
@@ -1170,9 +1219,20 @@ ARM_FUNC_START aeabi_idivmod
/* ------------------------------------------------------------------------ */
#ifdef L_modsi3
- FUNC_START modsi3
+#if defined(__ARM_ARCH_EXT_IDIV__)
-#ifdef __thumb__
+ ARM_FUNC_START modsi3
+
+ cmp r1, #0
+ beq LSYM(Ldiv0)
+
+ sdiv r2, r0, r1
+ mls r0, r1, r2, r0
+ RET
+
+#elif defined(__thumb__)
+
+ FUNC_START modsi3
mov curbit, #1
cmp divisor, #0
@@ -1204,6 +1264,8 @@ LSYM(Lover12):
#else /* ARM version. */
+ FUNC_START modsi3
+
cmp r1, #0
beq LSYM(Ldiv0)
rsbmi r1, r1, #0 @ loops below use unsigned.
diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S
index f7a8f6335c4..c592c4caa5d 100644
--- a/libgcc/config/avr/lib1funcs.S
+++ b/libgcc/config/avr/lib1funcs.S
@@ -61,6 +61,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#endif
.endm
+.macro wmov r_dest, r_src
+#if defined (__AVR_HAVE_MOVW__)
+ movw \r_dest, \r_src
+#else
+ mov \r_dest, \r_src
+ mov \r_dest+1, \r_src+1
+#endif
+.endm
+
#if defined (__AVR_HAVE_JMP_CALL__)
#define XCALL call
#define XJMP jmp
@@ -846,6 +855,352 @@ __divmodsi4_exit:
ENDF __divmodsi4
#endif /* defined (L_divmodsi4) */
+
+/*******************************************************
+ Division 64 / 64
+ Modulo 64 % 64
+*******************************************************/
+
+;; Use Speed-optimized Version on "big" Devices, i.e. Devices with
+;; at least 16k of Program Memory. For smaller Devices, depend
+;; on MOVW.
+
+#if defined (__AVR_HAVE_JMP_CALL__)
+# define SPEED_DIV 8
+#elif defined (__AVR_HAVE_MOVW__)
+# define SPEED_DIV 16
+#else
+# define SPEED_DIV 0
+#endif
+
+;; A[0..7]: In: Dividend;
+;; Out: Quotient (T = 0)
+;; Out: Remainder (T = 1)
+#define A0 18
+#define A1 A0+1
+#define A2 A0+2
+#define A3 A0+3
+#define A4 A0+4
+#define A5 A0+5
+#define A6 A0+6
+#define A7 A0+7
+
+;; B[0..7]: In: Divisor; Out: Clobber
+#define B0 10
+#define B1 B0+1
+#define B2 B0+2
+#define B3 B0+3
+#define B4 B0+4
+#define B5 B0+5
+#define B6 B0+6
+#define B7 B0+7
+
+;; C[0..7]: Expand remainder; Out: Remainder (unused)
+#define C0 8
+#define C1 C0+1
+#define C2 30
+#define C3 C2+1
+#define C4 28
+#define C5 C4+1
+#define C6 26
+#define C7 C6+1
+
+;; Holds Signs during Division Routine
+#define SS __tmp_reg__
+
+;; Bit-Counter in Division Routine
+#define R_cnt __zero_reg__
+
+;; Scratch Register for Negation
+#define NN r31
+
+#if defined (L_udivdi3)
+
+;; R25:R18 = R24:R18 umod R17:R10
+;; Ordinary ABI-Function
+
+DEFUN __umoddi3
+ set
+ rjmp __udivdi3_umoddi3
+ENDF __umoddi3
+
+;; R25:R18 = R24:R18 udiv R17:R10
+;; Ordinary ABI-Function
+
+DEFUN __udivdi3
+ clt
+ENDF __udivdi3
+
+DEFUN __udivdi3_umoddi3
+ push C0
+ push C1
+ push C4
+ push C5
+ XCALL __udivmod64
+ pop C5
+ pop C4
+ pop C1
+ pop C0
+ ret
+ENDF __udivdi3_umoddi3
+#endif /* L_udivdi3 */
+
+#if defined (L_udivmod64)
+
+;; Worker Routine for 64-Bit unsigned Quotient and Remainder Computation
+;; No Registers saved/restored; the Callers will take Care.
+;; Preserves B[] and T-flag
+;; T = 0: Compute Quotient in A[]
+;; T = 1: Compute Remainder in A[] and shift SS one Bit left
+
+DEFUN __udivmod64
+
+ ;; Clear Remainder (C6, C7 will follow)
+ clr C0
+ clr C1
+ wmov C2, C0
+ wmov C4, C0
+ ldi C7, 64
+
+#if SPEED_DIV == 0 || SPEED_DIV == 16
+ ;; Initialize Loop-Counter
+ mov R_cnt, C7
+ wmov C6, C0
+#endif /* SPEED_DIV */
+
+#if SPEED_DIV == 8
+
+ push A7
+ clr C6
+
+1: ;; Compare shifted Devidend against Divisor
+ ;; If -- even after Shifting -- it is smaller...
+ CP A7,B0 $ cpc C0,B1 $ cpc C1,B2 $ cpc C2,B3
+ cpc C3,B4 $ cpc C4,B5 $ cpc C5,B6 $ cpc C6,B7
+ brcc 2f
+
+ ;; ...then we can subtract it. Thus, it is legal to shift left
+ $ mov C6,C5 $ mov C5,C4 $ mov C4,C3
+ mov C3,C2 $ mov C2,C1 $ mov C1,C0 $ mov C0,A7
+ mov A7,A6 $ mov A6,A5 $ mov A5,A4 $ mov A4,A3
+ mov A3,A2 $ mov A2,A1 $ mov A1,A0 $ clr A0
+
+ ;; 8 Bits are done
+ subi C7, 8
+ brne 1b
+
+ ;; Shifted 64 Bits: A7 has traveled to C7
+ pop C7
+ ;; Divisor is greater than Dividend. We have:
+ ;; A[] % B[] = A[]
+ ;; A[] / B[] = 0
+ ;; Thus, we can return immediately
+ rjmp 5f
+
+2: ;; Initialze Bit-Counter with Number of Bits still to be performed
+ mov R_cnt, C7
+
+ ;; Push of A7 is not needed because C7 is still 0
+ pop C7
+ clr C7
+
+#elif SPEED_DIV == 16
+
+ ;; Compare shifted Dividend against Divisor
+ cp A7, B3
+ cpc C0, B4
+ cpc C1, B5
+ cpc C2, B6
+ cpc C3, B7
+ brcc 2f
+
+ ;; Divisor is greater than shifted Dividen: We can shift the Dividend
+ ;; and it is still smaller than the Divisor --> Shift one 32-Bit Chunk
+ wmov C2,A6 $ wmov C0,A4
+ wmov A6,A2 $ wmov A4,A0
+ wmov A2,C6 $ wmov A0,C4
+
+ ;; Set Bit Counter to 32
+ lsr R_cnt
+2:
+#elif SPEED_DIV
+#error SPEED_DIV = ?
+#endif /* SPEED_DIV */
+
+;; The very Division + Remainder Routine
+
+3: ;; Left-shift Dividend...
+ lsl A0 $ rol A1 $ rol A2 $ rol A3
+ rol A4 $ rol A5 $ rol A6 $ rol A7
+
+ ;; ...into Remainder
+ rol C0 $ rol C1 $ rol C2 $ rol C3
+ rol C4 $ rol C5 $ rol C6 $ rol C7
+
+ ;; Compare Remainder and Divisor
+ CP C0,B0 $ cpc C1,B1 $ cpc C2,B2 $ cpc C3,B3
+ cpc C4,B4 $ cpc C5,B5 $ cpc C6,B6 $ cpc C7,B7
+
+ brcs 4f
+
+ ;; Divisor fits into Remainder: Subtract it from Remainder...
+ SUB C0,B0 $ sbc C1,B1 $ sbc C2,B2 $ sbc C3,B3
+ sbc C4,B4 $ sbc C5,B5 $ sbc C6,B6 $ sbc C7,B7
+
+ ;; ...and set according Bit in the upcoming Quotient
+ ;; The Bit will travel to its final Position
+ ori A0, 1
+
+4: ;; This Bit is done
+ dec R_cnt
+ brne 3b
+ ;; __zero_reg__ is 0 again
+
+ ;; T = 0: We are fine with the Quotient in A[]
+ ;; T = 1: Copy Remainder to A[]
+5: brtc 6f
+ wmov A0, C0
+ wmov A2, C2
+ wmov A4, C4
+ wmov A6, C6
+ ;; Move the Sign of the Result to SS.7
+ lsl SS
+
+6: ret
+
+ENDF __udivmod64
+#endif /* L_udivmod64 */
+
+
+#if defined (L_divdi3)
+
+;; R25:R18 = R24:R18 mod R17:R10
+;; Ordinary ABI-Function
+
+DEFUN __moddi3
+ set
+ rjmp __divdi3_moddi3
+ENDF __moddi3
+
+;; R25:R18 = R24:R18 div R17:R10
+;; Ordinary ABI-Function
+
+DEFUN __divdi3
+ clt
+ENDF __divdi3
+
+DEFUN __divdi3_moddi3
+#if SPEED_DIV
+ mov r31, A7
+ or r31, B7
+ brmi 0f
+ ;; Both Signs are 0: the following Complexitiy is not needed
+ XJMP __udivdi3_umoddi3
+#endif /* SPEED_DIV */
+
+0: ;; The Prologue
+ ;; Save Z = 12 Registers: Y, 17...8
+ ;; No Frame needed (X = 0)
+ clr r26
+ clr r27
+ ldi r30, lo8(gs(1f))
+ ldi r31, hi8(gs(1f))
+ XJMP __prologue_saves__ + ((18 - 12) * 2)
+
+1: ;; SS.7 will contain the Sign of the Quotient (A.sign * B.sign)
+ ;; SS.6 will contain the Sign of the Remainder (A.sign)
+ mov SS, A7
+ asr SS
+ ;; Adjust Dividend's Sign as needed
+#if SPEED_DIV
+ ;; Compiling for Speed we know that at least one Sign must be < 0
+ ;; Thus, if A[] >= 0 then we know B[] < 0
+ brpl 22f
+#else
+ brpl 21f
+#endif /* SPEED_DIV */
+
+ XCALL __negdi2
+
+ ;; Adjust Divisor's Sign and SS.7 as needed
+21: tst B7
+ brpl 3f
+22: ldi NN, 1 << 7
+ eor SS, NN
+
+ ldi NN, -1
+ com B4 $ com B5 $ com B6 $ com B7
+ $ com B1 $ com B2 $ com B3
+ NEG B0
+ $ sbc B1,NN $ sbc B2,NN $ sbc B3,NN
+ sbc B4,NN $ sbc B5,NN $ sbc B6,NN $ sbc B7,NN
+
+3: ;; Do the unsigned 64-Bit Division/Modulo (depending on T-flag)
+ XCALL __udivmod64
+
+ ;; Adjust Result's Sign
+#ifdef __AVR_ERRATA_SKIP_JMP_CALL__
+ tst SS
+ brpl 4f
+#else
+ sbrc SS, 7
+#endif /* __AVR_HAVE_JMP_CALL__ */
+ XCALL __negdi2
+
+4: ;; Epilogue: Restore the Z = 12 Registers and return
+ in r28, __SP_L__
+ in r29, __SP_H__
+ ldi r30, 12
+ XJMP __epilogue_restores__ + ((18 - 12) * 2)
+
+ENDF __divdi3_moddi3
+
+#undef R_cnt
+#undef SS
+#undef NN
+
+#endif /* L_divdi3 */
+
+#if defined (L_negdi2)
+DEFUN __negdi2
+
+ com A4 $ com A5 $ com A6 $ com A7
+ $ com A1 $ com A2 $ com A3
+ NEG A0
+ $ sbci A1,-1 $ sbci A2,-1 $ sbci A3,-1
+ sbci A4,-1 $ sbci A5,-1 $ sbci A6,-1 $ sbci A7,-1
+ ret
+
+ENDF __negdi2
+#endif /* L_negdi2 */
+
+#undef C7
+#undef C6
+#undef C5
+#undef C4
+#undef C3
+#undef C2
+#undef C1
+#undef C0
+
+#undef B7
+#undef B6
+#undef B5
+#undef B4
+#undef B3
+#undef B2
+#undef B1
+#undef B0
+
+#undef A7
+#undef A6
+#undef A5
+#undef A4
+#undef A3
+#undef A2
+#undef A1
+#undef A0
+
.section .text.libgcc.prologue, "ax", @progbits
@@ -854,6 +1209,7 @@ ENDF __divmodsi4
**********************************/
#if defined (L_prologue)
+;; This function does not clobber T-flag; 64-bit division relies on it
DEFUN __prologue_saves__
push r2
push r3
@@ -1181,6 +1537,119 @@ DEFUN __tablejump_elpm__
ENDF __tablejump_elpm__
#endif /* defined (L_tablejump_elpm) */
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Loading n bytes from Flash; n = 3,4
+;; R22... = Flash[Z]
+;; Clobbers: __tmp_reg__
+
+#if (defined (L_load_3) \
+ || defined (L_load_4)) \
+ && !defined (__AVR_HAVE_LPMX__)
+
+;; Destination
+#define D0 22
+#define D1 D0+1
+#define D2 D0+2
+#define D3 D0+3
+
+.macro .load dest, n
+ lpm
+ mov \dest, r0
+.if \dest != D0+\n-1
+ adiw r30, 1
+.else
+ sbiw r30, \n-1
+.endif
+.endm
+
+#if defined (L_load_3)
+DEFUN __load_3
+ push D3
+ XCALL __load_4
+ pop D3
+ ret
+ENDF __load_3
+#endif /* L_load_3 */
+
+#if defined (L_load_4)
+DEFUN __load_4
+ .load D0, 4
+ .load D1, 4
+ .load D2, 4
+ .load D3, 4
+ ret
+ENDF __load_4
+#endif /* L_load_4 */
+
+#endif /* L_load_3 || L_load_3 */
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Loading n bytes from Flash; n = 2,3,4
+;; R22... = Flash[R21:Z]
+;; Clobbers: __tmp_reg__, R21, R30, R31
+
+#if (defined (L_xload_2) \
+ || defined (L_xload_3) \
+ || defined (L_xload_4)) \
+ && defined (__AVR_HAVE_ELPM__) \
+ && !defined (__AVR_HAVE_ELPMX__)
+
+#if !defined (__AVR_HAVE_RAMPZ__)
+#error Need RAMPZ
+#endif /* have RAMPZ */
+
+;; Destination
+#define D0 22
+#define D1 D0+1
+#define D2 D0+2
+#define D3 D0+3
+
+;; Register containing bits 16+ of the address
+
+#define HHI8 21
+
+.macro .xload dest, n
+ elpm
+ mov \dest, r0
+.if \dest != D0+\n-1
+ adiw r30, 1
+ adc HHI8, __zero_reg__
+ out __RAMPZ__, HHI8
+.endif
+.endm
+
+#if defined (L_xload_2)
+DEFUN __xload_2
+ out __RAMPZ__, HHI8
+ .xload D0, 2
+ .xload D1, 2
+ ret
+ENDF __xload_2
+#endif /* L_xload_2 */
+
+#if defined (L_xload_3)
+DEFUN __xload_3
+ out __RAMPZ__, HHI8
+ .xload D0, 3
+ .xload D1, 3
+ .xload D2, 3
+ ret
+ENDF __xload_3
+#endif /* L_xload_3 */
+
+#if defined (L_xload_4)
+DEFUN __xload_4
+ out __RAMPZ__, HHI8
+ .xload D0, 4
+ .xload D1, 4
+ .xload D2, 4
+ .xload D3, 4
+ ret
+ENDF __xload_4
+#endif /* L_xload_4 */
+
+#endif /* L_xload_{2|3|4} && ELPM */
+
.section .text.libgcc.builtins, "ax", @progbits
diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr
index cd529ae8606..b5c8d05186a 100644
--- a/libgcc/config/avr/t-avr
+++ b/libgcc/config/avr/t-avr
@@ -15,12 +15,17 @@ LIB1ASMFUNCS = \
_divmodpsi4 _udivmodpsi4 \
_udivmodsi4 \
_divmodsi4 \
+ _divdi3 _udivdi3 \
+ _udivmod64 \
+ _negdi2 \
_prologue \
_epilogue \
_exit \
_cleanup \
_tablejump \
_tablejump_elpm \
+ _load_3 _load_4 \
+ _xload_2 _xload_3 _xload_4 \
_copy_data \
_clear_bss \
_ctors \
@@ -48,6 +53,7 @@ LIB1ASMFUNCS = \
_fmul _fmuls _fmulsu
LIB2FUNCS_EXCLUDE = \
+ _moddi3 _umoddi3 \
_clz
# We do not have the DF type.
diff --git a/libgcc/config/darwin-crt-tm.c b/libgcc/config/darwin-crt-tm.c
new file mode 100644
index 00000000000..23113374eea
--- /dev/null
+++ b/libgcc/config/darwin-crt-tm.c
@@ -0,0 +1,77 @@
+/* Provide the runtime infrastructure for the transactional memory lib.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+ Contributed by Iain Sandoe <iains@gcc.gnu.org>
+
+ 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 <mach-o/dyld.h>
+
+/* not listed in mach-o/dyld.h for some reason. */
+extern char * getsectdata (const char*,const char*,unsigned long*);
+
+#define WEAK __attribute__((weak))
+
+extern void _ITM_registerTMCloneTable (void *, size_t) WEAK;
+extern void _ITM_deregisterTMCloneTable (void *) WEAK;
+
+#ifdef START
+
+void __doTMRegistrations (void) __attribute__ ((constructor));
+
+void __doTMRegistrations (void)
+{
+ char * tm_clone_table_sect_data;
+ unsigned long tmct_siz;
+
+ tm_clone_table_sect_data = getsectdata ("__DATA",
+ "__tm_clone_table",
+ &tmct_siz);
+ tmct_siz /= (sizeof (size_t) * 2);
+ if (_ITM_registerTMCloneTable != NULL
+ && tm_clone_table_sect_data != NULL
+ && tmct_siz > 0)
+ _ITM_registerTMCloneTable (tm_clone_table_sect_data, (size_t)tmct_siz);
+}
+
+#endif
+
+#ifdef END
+
+void __doTMdeRegistrations (void) __attribute__ ((destructor));
+
+void __doTMdeRegistrations (void)
+{
+ char * tm_clone_table_sect_data;
+ unsigned long tmct_siz;
+
+ tm_clone_table_sect_data = getsectdata ("__DATA",
+ "__tm_clone_table",
+ &tmct_siz);
+
+ if (_ITM_deregisterTMCloneTable != NULL
+ && tm_clone_table_sect_data != NULL
+ && tmct_siz > 0)
+ _ITM_deregisterTMCloneTable (tm_clone_table_sect_data);
+
+}
+
+#endif
diff --git a/libgcc/config/i386/t-darwin64 b/libgcc/config/i386/t-darwin64
deleted file mode 100644
index 30cf58b38f9..00000000000
--- a/libgcc/config/i386/t-darwin64
+++ /dev/null
@@ -1,2 +0,0 @@
-LIB2_SIDITI_CONV_FUNCS = yes
-LIB2ADD = $(srcdir)/config/darwin-64.c
diff --git a/libgcc/config/m68k/linux-atomic.c b/libgcc/config/m68k/linux-atomic.c
new file mode 100644
index 00000000000..6e81d6b5d5e
--- /dev/null
+++ b/libgcc/config/m68k/linux-atomic.c
@@ -0,0 +1,211 @@
+/* Linux-specific atomic operations for m68k Linux.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+ Based on code contributed by CodeSourcery for ARM EABI Linux.
+
+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/>. */
+
+/* Coldfire dropped the CAS instruction from the base M68K ISA.
+
+ GCC automatically issues a asm memory barrier when it encounters
+ a __sync_synchronize builtin. Thus, we do not need to define this
+ builtin.
+
+ We implement byte, short and int versions of each atomic operation
+ using the kernel helper defined below. There is no support for
+ 64-bit operations yet. */
+
+#include <asm/unistd.h>
+#include <stdbool.h>
+
+#ifndef __NR_atomic_cmpxchg_32
+#define __NR_atomic_cmpxchg_32 335
+#endif
+
+/* Kernel helper for compare-and-exchange a 32-bit value. */
+static inline unsigned
+__kernel_cmpxchg (unsigned *mem, unsigned oldval, unsigned newval)
+{
+ register unsigned *a0 asm("a0") = mem;
+ register unsigned d2 asm("d2") = oldval;
+ register unsigned d1 asm("d1") = newval;
+ register unsigned d0 asm("d0") = __NR_atomic_cmpxchg_32;
+
+ asm volatile ("trap #0"
+ : "=r"(d0), "=r"(d1), "=r"(a0)
+ : "r"(d0), "r"(d1), "r"(d2), "r"(a0)
+ : "memory", "a1");
+
+ return d0;
+}
+
+#define HIDDEN __attribute__ ((visibility ("hidden")))
+
+/* Big endian masks */
+#define INVERT_MASK_1 24
+#define INVERT_MASK_2 16
+
+#define MASK_1 0xffu
+#define MASK_2 0xffffu
+
+#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH
+#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH
+
+#define WORD_SYNC_OP(OP, PFX_OP, INF_OP, RETURN) \
+ unsigned HIDDEN \
+ NAME##_##RETURN (OP, 4) (unsigned *ptr, unsigned val) \
+ { \
+ unsigned oldval, newval, cmpval = *ptr; \
+ \
+ do { \
+ oldval = cmpval; \
+ newval = PFX_OP (oldval INF_OP val); \
+ cmpval = __kernel_cmpxchg (ptr, oldval, newval); \
+ } while (__builtin_expect (oldval != cmpval, 0)); \
+ \
+ return RETURN; \
+ }
+
+#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \
+ TYPE HIDDEN \
+ NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE sval) \
+ { \
+ unsigned *wordptr = (unsigned *) ((unsigned long) ptr & ~3); \
+ unsigned int mask, shift, oldval, newval, cmpval, wval; \
+ \
+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
+ mask = MASK_##WIDTH << shift; \
+ wval = (sval & MASK_##WIDTH) << shift; \
+ \
+ cmpval = *wordptr; \
+ do { \
+ oldval = cmpval; \
+ newval = PFX_OP (oldval INF_OP wval); \
+ newval = (newval & mask) | (oldval & ~mask); \
+ cmpval = __kernel_cmpxchg (wordptr, oldval, newval); \
+ } while (__builtin_expect (oldval != cmpval, 0)); \
+ \
+ return (RETURN >> shift) & MASK_##WIDTH; \
+ }
+
+WORD_SYNC_OP (add, , +, oldval)
+WORD_SYNC_OP (sub, , -, oldval)
+WORD_SYNC_OP (or, , |, oldval)
+WORD_SYNC_OP (and, , &, oldval)
+WORD_SYNC_OP (xor, , ^, oldval)
+WORD_SYNC_OP (nand, ~, &, oldval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, oldval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, oldval)
+
+WORD_SYNC_OP (add, , +, newval)
+WORD_SYNC_OP (sub, , -, newval)
+WORD_SYNC_OP (or, , |, newval)
+WORD_SYNC_OP (and, , &, newval)
+WORD_SYNC_OP (xor, , ^, newval)
+WORD_SYNC_OP (nand, ~, &, newval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, newval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, newval)
+
+unsigned HIDDEN
+__sync_val_compare_and_swap_4 (unsigned *ptr, unsigned oldval, unsigned newval)
+{
+ return __kernel_cmpxchg (ptr, oldval, newval);
+}
+
+bool HIDDEN
+__sync_bool_compare_and_swap_4 (unsigned *ptr, unsigned oldval,
+ unsigned newval)
+{
+ return __kernel_cmpxchg (ptr, oldval, newval) == oldval;
+}
+
+#define SUBWORD_VAL_CAS(TYPE, WIDTH) \
+ TYPE HIDDEN \
+ __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE soldval, \
+ TYPE snewval) \
+ { \
+ unsigned *wordptr = (unsigned *)((unsigned long) ptr & ~3); \
+ unsigned int mask, shift, woldval, wnewval; \
+ unsigned oldval, newval, cmpval; \
+ \
+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
+ mask = MASK_##WIDTH << shift; \
+ woldval = (soldval & MASK_##WIDTH) << shift; \
+ wnewval = (snewval & MASK_##WIDTH) << shift; \
+ cmpval = *wordptr; \
+ \
+ do { \
+ oldval = cmpval; \
+ if ((oldval & mask) != woldval) \
+ break; \
+ newval = (oldval & ~mask) | wnewval; \
+ cmpval = __kernel_cmpxchg (wordptr, oldval, newval); \
+ } while (__builtin_expect (oldval != cmpval, 0)); \
+ \
+ return (oldval >> shift) & MASK_##WIDTH; \
+ }
+
+SUBWORD_VAL_CAS (unsigned short, 2)
+SUBWORD_VAL_CAS (unsigned char, 1)
+
+#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \
+ bool HIDDEN \
+ __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
+ TYPE newval) \
+ { \
+ return (__sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval) \
+ == oldval); \
+ }
+
+SUBWORD_BOOL_CAS (unsigned short, 2)
+SUBWORD_BOOL_CAS (unsigned char, 1)
+
+#undef NAME_oldval
+#define NAME_oldval(OP, WIDTH) __sync_lock_##OP##_##WIDTH
+#define COMMA ,
+
+WORD_SYNC_OP (test_and_set, , COMMA, oldval)
+SUBWORD_SYNC_OP (test_and_set, , COMMA, unsigned short, 1, oldval)
+SUBWORD_SYNC_OP (test_and_set, , COMMA, unsigned short, 2, oldval)
diff --git a/libgcc/config/m68k/t-linux b/libgcc/config/m68k/t-linux
new file mode 100644
index 00000000000..06f0fe09f25
--- /dev/null
+++ b/libgcc/config/m68k/t-linux
@@ -0,0 +1 @@
+LIB2ADD_ST = $(srcdir)/config/m68k/linux-atomic.c
diff --git a/libgcc/config/rs6000/t-ppccomm b/libgcc/config/rs6000/t-ppccomm
index e9233688268..fb812d3801f 100644
--- a/libgcc/config/rs6000/t-ppccomm
+++ b/libgcc/config/rs6000/t-ppccomm
@@ -1,27 +1,8 @@
LIB2ADD += $(srcdir)/config/rs6000/ibm-ldouble.c \
$(srcdir)/config/rs6000/tramp.S
-# These can't end up in shared libgcc
+# This can't end up in shared libgcc
LIB2ADD_ST += \
- $(srcdir)/config/rs6000/crtsavfpr.S \
- $(srcdir)/config/rs6000/crtresfpr.S \
- $(srcdir)/config/rs6000/crtsavgpr.S \
- $(srcdir)/config/rs6000/crtresgpr.S \
- $(srcdir)/config/rs6000/crtresxfpr.S \
- $(srcdir)/config/rs6000/crtresxgpr.S \
- $(srcdir)/config/rs6000/e500crtres32gpr.S \
- $(srcdir)/config/rs6000/e500crtres64gpr.S \
- $(srcdir)/config/rs6000/e500crtres64gprctr.S \
- $(srcdir)/config/rs6000/e500crtrest32gpr.S \
- $(srcdir)/config/rs6000/e500crtrest64gpr.S \
- $(srcdir)/config/rs6000/e500crtresx32gpr.S \
- $(srcdir)/config/rs6000/e500crtresx64gpr.S \
- $(srcdir)/config/rs6000/e500crtsav32gpr.S \
- $(srcdir)/config/rs6000/e500crtsav64gpr.S \
- $(srcdir)/config/rs6000/e500crtsav64gprctr.S \
- $(srcdir)/config/rs6000/e500crtsavg32gpr.S \
- $(srcdir)/config/rs6000/e500crtsavg64gpr.S \
- $(srcdir)/config/rs6000/e500crtsavg64gprctr.S \
$(srcdir)/config/rs6000/eabi.S
# We build {e,n}crti.o and {e,n}crtn.o, which serve to add begin and
diff --git a/libgcc/config/rs6000/t-ppccomm-ldbl b/libgcc/config/rs6000/t-ppccomm-ldbl
deleted file mode 100644
index f1d53606677..00000000000
--- a/libgcc/config/rs6000/t-ppccomm-ldbl
+++ /dev/null
@@ -1 +0,0 @@
-LIB2ADD += $(srcdir)/config/rs6000/ibm-ldouble.c
diff --git a/libgcc/config/rs6000/t-savresfgpr b/libgcc/config/rs6000/t-savresfgpr
new file mode 100644
index 00000000000..e2a951abd3f
--- /dev/null
+++ b/libgcc/config/rs6000/t-savresfgpr
@@ -0,0 +1,21 @@
+# These can't end up in shared libgcc
+LIB2ADD_ST += \
+ $(srcdir)/config/rs6000/crtsavfpr.S \
+ $(srcdir)/config/rs6000/crtresfpr.S \
+ $(srcdir)/config/rs6000/crtsavgpr.S \
+ $(srcdir)/config/rs6000/crtresgpr.S \
+ $(srcdir)/config/rs6000/crtresxfpr.S \
+ $(srcdir)/config/rs6000/crtresxgpr.S \
+ $(srcdir)/config/rs6000/e500crtres32gpr.S \
+ $(srcdir)/config/rs6000/e500crtres64gpr.S \
+ $(srcdir)/config/rs6000/e500crtres64gprctr.S \
+ $(srcdir)/config/rs6000/e500crtrest32gpr.S \
+ $(srcdir)/config/rs6000/e500crtrest64gpr.S \
+ $(srcdir)/config/rs6000/e500crtresx32gpr.S \
+ $(srcdir)/config/rs6000/e500crtresx64gpr.S \
+ $(srcdir)/config/rs6000/e500crtsav32gpr.S \
+ $(srcdir)/config/rs6000/e500crtsav64gpr.S \
+ $(srcdir)/config/rs6000/e500crtsav64gprctr.S \
+ $(srcdir)/config/rs6000/e500crtsavg32gpr.S \
+ $(srcdir)/config/rs6000/e500crtsavg64gpr.S \
+ $(srcdir)/config/rs6000/e500crtsavg64gprctr.S
diff --git a/libgcc/config/sh/t-netbsd b/libgcc/config/sh/t-netbsd
index d4df407fa16..3c5739e2ffc 100644
--- a/libgcc/config/sh/t-netbsd
+++ b/libgcc/config/sh/t-netbsd
@@ -1,5 +1,3 @@
LIB1ASMFUNCS_CACHE = _ic_invalidate
-LIB2ADD =
-
HOST_LIBGCC2_CFLAGS += -mieee
diff --git a/libgcc/config/t-darwin b/libgcc/config/t-darwin
index e32127e9d8a..3365f010225 100644
--- a/libgcc/config/t-darwin
+++ b/libgcc/config/t-darwin
@@ -3,6 +3,12 @@ crt3.o: $(srcdir)/config/darwin-crt3.c
$(crt_compile) \
-fno-tree-dominator-opts $(DARWIN_EXTRA_CRT_BUILD_CFLAGS) -c $<
+crttms.o: $(srcdir)/config/darwin-crt-tm.c
+ $(crt_compile) $(DARWIN_EXTRA_CRT_BUILD_CFLAGS) -DSTART -c $<
+
+crttme.o: $(srcdir)/config/darwin-crt-tm.c
+ $(crt_compile) $(DARWIN_EXTRA_CRT_BUILD_CFLAGS) -DEND -c $<
+
# -pipe because there's an assembler bug, 4077127, which causes
# it to not properly process the first # directive, causing temporary
# file names to appear in stabs, causing the bootstrap to fail. Using -pipe
diff --git a/libgcc/crtstuff.c b/libgcc/crtstuff.c
index 66b2cdf2446..77b8d4201cd 100644
--- a/libgcc/crtstuff.c
+++ b/libgcc/crtstuff.c
@@ -127,6 +127,10 @@ call_ ## FUNC (void) \
# define HIDDEN_DTOR_LIST_END
#endif
+#if !defined(USE_TM_CLONE_REGISTRY) && defined(OBJECT_FORMAT_ELF)
+# define USE_TM_CLONE_REGISTRY 1
+#endif
+
/* We do not want to add the weak attribute to the declarations of these
routines in unwind-dw2-fde.h because that will cause the definition of
these symbols to be weak as well.
@@ -163,6 +167,10 @@ extern void __do_global_ctors_1 (void);
/* Likewise for _Jv_RegisterClasses. */
extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
+/* Likewise for transactional memory clone tables. */
+extern void _ITM_registerTMCloneTable (void *, size_t) TARGET_ATTRIBUTE_WEAK;
+extern void _ITM_deregisterTMCloneTable (void *) TARGET_ATTRIBUTE_WEAK;
+
#ifdef OBJECT_FORMAT_ELF
/* Declare a pointer to void function type. */
@@ -242,6 +250,55 @@ STATIC void *__JCR_LIST__[]
= { };
#endif /* JCR_SECTION_NAME */
+#if USE_TM_CLONE_REGISTRY
+STATIC func_ptr __TMC_LIST__[]
+ __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void*))))
+ = { };
+# ifdef HAVE_GAS_HIDDEN
+extern func_ptr __TMC_END__[] __attribute__((__visibility__ ("hidden")));
+# endif
+
+static inline void
+deregister_tm_clones (void)
+{
+ void (*fn) (void *);
+
+#ifdef HAVE_GAS_HIDDEN
+ if (__TMC_END__ - __TMC_LIST__ == 0)
+ return;
+#else
+ if (__TMC_LIST__[0] == NULL)
+ return;
+#endif
+
+ fn = _ITM_deregisterTMCloneTable;
+ __asm ("" : "+r" (fn));
+ if (fn)
+ fn (__TMC_LIST__);
+}
+
+static inline void
+register_tm_clones (void)
+{
+ void (*fn) (void *, size_t);
+ size_t size;
+
+#ifdef HAVE_GAS_HIDDEN
+ size = (__TMC_END__ - __TMC_LIST__) / 2;
+#else
+ for (size = 0; __TMC_LIST__[size * 2] != NULL; size++)
+ continue;
+#endif
+ if (size == 0)
+ return;
+
+ fn = _ITM_registerTMCloneTable;
+ __asm ("" : "+r" (fn));
+ if (fn)
+ fn (__TMC_LIST__, size);
+}
+#endif /* USE_TM_CLONE_REGISTRY */
+
#if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP)
#ifdef OBJECT_FORMAT_ELF
@@ -331,6 +388,10 @@ __do_global_dtors_aux (void)
}
#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
+#if USE_TM_CLONE_REGISTRY
+ deregister_tm_clones ();
+#endif /* USE_TM_CLONE_REGISTRY */
+
#ifdef USE_EH_FRAME_REGISTRY
#ifdef CRT_GET_RFIB_DATA
/* If we used the new __register_frame_info_bases interface,
@@ -362,7 +423,9 @@ __do_global_dtors_aux_1 (void)
CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_dtors_aux_1)
#endif
-#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
+#if defined(USE_EH_FRAME_REGISTRY) \
+ || defined(JCR_SECTION_NAME) \
+ || defined(USE_TM_CLONE_REGISTRY)
/* Stick a call to __register_frame_info into the .init section. For some
reason calls with no arguments work more reliably in .init, so stick the
call in another function. */
@@ -383,6 +446,7 @@ frame_dummy (void)
__register_frame_info (__EH_FRAME_BEGIN__, &object);
#endif /* CRT_GET_RFIB_DATA */
#endif /* USE_EH_FRAME_REGISTRY */
+
#ifdef JCR_SECTION_NAME
if (__JCR_LIST__[0])
{
@@ -392,6 +456,10 @@ frame_dummy (void)
register_classes (__JCR_LIST__);
}
#endif /* JCR_SECTION_NAME */
+
+#if USE_TM_CLONE_REGISTRY
+ register_tm_clones ();
+#endif /* USE_TM_CLONE_REGISTRY */
}
#ifdef INIT_SECTION_ASM_OP
@@ -401,7 +469,7 @@ static func_ptr __frame_dummy_init_array_entry[]
__attribute__ ((__used__, section(".init_array")))
= { frame_dummy };
#endif /* !defined(INIT_SECTION_ASM_OP) */
-#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
+#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME || USE_TM_CLONE_REGISTRY */
#else /* OBJECT_FORMAT_ELF */
@@ -458,13 +526,19 @@ __do_global_dtors (void)
for (p = __DTOR_LIST__ + 1; (f = *p); p++)
f ();
+#if USE_TM_CLONE_REGISTRY
+ deregister_tm_clones ();
+#endif /* USE_TM_CLONE_REGISTRY */
+
#ifdef USE_EH_FRAME_REGISTRY
if (__deregister_frame_info)
__deregister_frame_info (__EH_FRAME_BEGIN__);
#endif
}
-#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
+#if defined(USE_EH_FRAME_REGISTRY) \
+ || defined(JCR_SECTION_NAME) \
+ || defined(USE_TM_CLONE_REGISTRY)
/* A helper function for __do_global_ctors, which is in crtend.o. Here
in crtbegin.o, we can reference a couple of symbols not visible there.
Plus, since we're before libgcc.a, we have no problems referencing
@@ -477,6 +551,7 @@ __do_global_ctors_1(void)
if (__register_frame_info)
__register_frame_info (__EH_FRAME_BEGIN__, &object);
#endif
+
#ifdef JCR_SECTION_NAME
if (__JCR_LIST__[0])
{
@@ -486,8 +561,12 @@ __do_global_ctors_1(void)
register_classes (__JCR_LIST__);
}
#endif
+
+#if USE_TM_CLONE_REGISTRY
+ register_tm_clones ();
+#endif /* USE_TM_CLONE_REGISTRY */
}
-#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
+#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME || USE_TM_CLONE_REGISTRY */
#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
#error "What are you doing with crtstuff.c, then?"
@@ -571,6 +650,19 @@ STATIC void *__JCR_END__[1]
= { 0 };
#endif /* JCR_SECTION_NAME */
+#if USE_TM_CLONE_REGISTRY
+# ifndef HAVE_GAS_HIDDEN
+static
+# endif
+func_ptr __TMC_END__[]
+ __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void *))))
+# ifdef HAVE_GAS_HIDDEN
+ __attribute__((__visibility__ ("hidden"))) = { };
+# else
+ = { 0, 0 };
+# endif
+#endif /* USE_TM_CLONE_REGISTRY */
+
#ifdef INIT_ARRAY_SECTION_ASM_OP
/* If we are using .init_array, there is nothing to do. */
@@ -635,7 +727,9 @@ void
__do_global_ctors (void)
{
func_ptr *p;
-#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
+#if defined(USE_EH_FRAME_REGISTRY) \
+ || defined(JCR_SECTION_NAME) \
+ || defined(USE_TM_CLONE_REGISTRY)
__do_global_ctors_1();
#endif
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c
index 00a3b1c3bf0..4dbaa0e4cdc 100644
--- a/libgcc/generic-morestack.c
+++ b/libgcc/generic-morestack.c
@@ -115,6 +115,14 @@ extern void *
__splitstack_makecontext (size_t, void *context[10], size_t *)
__attribute__ ((visibility ("default")));
+extern void *
+__splitstack_resetcontext (void *context[10], size_t *)
+ __attribute__ ((visibility ("default")));
+
+extern void
+__splitstack_releasecontext (void *context[10])
+ __attribute__ ((visibility ("default")));
+
extern void
__splitstack_block_signals_context (void *context[10], int *, int *)
__attribute__ ((visibility ("default")));
@@ -911,15 +919,23 @@ __splitstack_find (void *segment_arg, void *sp, size_t *len,
nsp = (char *) segment->old_stack;
+ if (nsp == NULL)
+ {
+ /* We've reached the top of the stack. */
+ *next_segment = (void *) (uintptr_type) 2;
+ }
+ else
+ {
#if defined (__x86_64__)
- nsp -= 12 * sizeof (void *);
+ nsp -= 12 * sizeof (void *);
#elif defined (__i386__)
- nsp -= 6 * sizeof (void *);
+ nsp -= 6 * sizeof (void *);
#else
#error "unrecognized target"
#endif
- *next_sp = (void *) nsp;
+ *next_sp = (void *) nsp;
+ }
#ifdef STACK_GROWS_DOWNWARD
*len = (char *) (segment + 1) + segment->size - (char *) sp;
@@ -1037,6 +1053,60 @@ __splitstack_makecontext (size_t stack_size, void *context[NUMBER_OFFSETS],
return (void *) (segment + 1);
}
+/* Given an existing split stack context, reset it back to the start
+ of the stack. Return the stack pointer and size, appropriate for
+ use with makecontext. This may be used if a coroutine exits, in
+ order to reuse the stack segments for a new coroutine. */
+
+void *
+__splitstack_resetcontext (void *context[10], size_t *size)
+{
+ struct stack_segment *segment;
+ void *initial_sp;
+ size_t initial_size;
+ void *ret;
+
+ /* Reset the context assuming that MORESTACK_SEGMENTS, INITIAL_SP
+ and INITIAL_SP_LEN are correct. */
+
+ segment = context[MORESTACK_SEGMENTS];
+ context[CURRENT_SEGMENT] = segment;
+ context[CURRENT_STACK] = NULL;
+ if (segment == NULL)
+ {
+ initial_sp = context[INITIAL_SP];
+ initial_size = (uintptr_type) context[INITIAL_SP_LEN];
+ ret = initial_sp;
+#ifdef STACK_GROWS_DOWNWARD
+ ret = (void *) ((char *) ret - initial_size);
+#endif
+ }
+ else
+ {
+#ifdef STACK_GROWS_DOWNWARD
+ initial_sp = (void *) ((char *) (segment + 1) + segment->size);
+#else
+ initial_sp = (void *) (segment + 1);
+#endif
+ initial_size = segment->size;
+ ret = (void *) (segment + 1);
+ }
+ context[STACK_GUARD] = __morestack_make_guard (initial_sp, initial_size);
+ context[BLOCK_SIGNALS] = NULL;
+ *size = initial_size;
+ return ret;
+}
+
+/* Release all the memory associated with a splitstack context. This
+ may be used if a coroutine exits and the associated stack should be
+ freed. */
+
+void
+__splitstack_releasecontext (void *context[10])
+{
+ __morestack_release_segments (context[MORESTACK_SEGMENTS], 1);
+}
+
/* Like __splitstack_block_signals, but operating on CONTEXT, rather
than on the current state. */
diff --git a/libgcc/libgcc-std.ver.in b/libgcc/libgcc-std.ver.in
index 2d66612d1c5..ec702952f9b 100644
--- a/libgcc/libgcc-std.ver.in
+++ b/libgcc/libgcc-std.ver.in
@@ -1932,4 +1932,6 @@ GCC_4.7.0 {
__splitstack_makecontext
__splitstack_block_signals_context
__splitstack_find_context
+ __splitstack_resetcontext
+ __splitstack_releasecontext
}
diff --git a/libgcc/static-object.mk b/libgcc/static-object.mk
index ab75d3288c3..930f009cd42 100644
--- a/libgcc/static-object.mk
+++ b/libgcc/static-object.mk
@@ -6,10 +6,15 @@ iter-items := $(filter-out $o,$(iter-items))
base := $(basename $(notdir $o))
+# Copy c_flags to a rule-specific copy and use the copy, to avoid the
+# following rules being affected by later changes to c_flags in the
+# including file.
+c_flags-$o := $(c_flags)
+
ifeq ($(suffix $o),.c)
$(base)$(objext): $o
- $(gcc_compile) $(c_flags) -c $< $(vis_hide)
+ $(gcc_compile) $(c_flags-$<) -c $< $(vis_hide)
else