diff options
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 139 | ||||
-rw-r--r-- | libgcc/Makefile.in | 8 | ||||
-rw-r--r-- | libgcc/config.host | 51 | ||||
-rw-r--r-- | libgcc/config/alpha/qrnnd.S | 12 | ||||
-rw-r--r-- | libgcc/config/arm/lib1funcs.S | 70 | ||||
-rw-r--r-- | libgcc/config/avr/lib1funcs.S | 469 | ||||
-rw-r--r-- | libgcc/config/avr/t-avr | 6 | ||||
-rw-r--r-- | libgcc/config/darwin-crt-tm.c | 77 | ||||
-rw-r--r-- | libgcc/config/i386/t-darwin64 | 2 | ||||
-rw-r--r-- | libgcc/config/m68k/linux-atomic.c | 211 | ||||
-rw-r--r-- | libgcc/config/m68k/t-linux | 1 | ||||
-rw-r--r-- | libgcc/config/rs6000/t-ppccomm | 21 | ||||
-rw-r--r-- | libgcc/config/rs6000/t-ppccomm-ldbl | 1 | ||||
-rw-r--r-- | libgcc/config/rs6000/t-savresfgpr | 21 | ||||
-rw-r--r-- | libgcc/config/sh/t-netbsd | 2 | ||||
-rw-r--r-- | libgcc/config/t-darwin | 6 | ||||
-rw-r--r-- | libgcc/crtstuff.c | 104 | ||||
-rw-r--r-- | libgcc/generic-morestack.c | 76 | ||||
-rw-r--r-- | libgcc/libgcc-std.ver.in | 2 | ||||
-rw-r--r-- | libgcc/static-object.mk | 7 |
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 |