diff options
author | Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> | 2011-11-02 15:23:48 +0000 |
---|---|---|
committer | Rainer Orth <ro@gcc.gnu.org> | 2011-11-02 15:23:48 +0000 |
commit | f9989b51a9bc3b0ad31bb5ad2c805ca03427801e (patch) | |
tree | a6dbc75c1a7630ada3b2b9cf8cb8ab6681e223c0 /libgcc | |
parent | 45b86625d7edd2278c0cdcf335e007a47671813f (diff) | |
download | gcc-f9989b51a9bc3b0ad31bb5ad2c805ca03427801e.zip gcc-f9989b51a9bc3b0ad31bb5ad2c805ca03427801e.tar.gz gcc-f9989b51a9bc3b0ad31bb5ad2c805ca03427801e.tar.bz2 |
Move libgcc2 to toplevel libgcc
toplevel:
* Makefile.tpl (EXTRA_GCC_FLAGS): Remove LIBGCC2_CFLAGS,
LIBGCC2_DEBUG_CFLAGS, LIBGCC2_INCLUDES.
* Makefile.in: Regenerate.
config:
* mh-interix (LIBGCC2_DEBUG_CFLAGS): Remove.
gcc:
* Makefile.in (LIBGCC2_DEBUG_CFLAGS LIBGCC2_CFLAGS)
(LIBGCC2_INCLUDES, TARGET_LIBGCC2_CFLAGS, LIB2FUNCS_EXTRA)
(LIB2FUNCS_STATIC_EXTRA, LIB2FUNCS_EXCLUDE, T, T_TARGET)
(INCLUDES_FOR_TARGET): Remove.
(LIBGCC2_CFLAGS): Don't export.
(LIB2FUNCS_ST, LIB2_DIVMOD_FUNCS, LIB2ADD, LIB2ADD_ST, srcdirify):
Remove.
(libgcc-support): Remove $(LIB2ADD), $(LIB2ADD_ST) dependencies.
(libgcc.mvars): Likewise.
Don't emit LIB2FUNCS_ST, LIB2FUNCS_EXCLUDE, LIB2ADD, LIB2ADD_ST,
LIB2_SIDITI_CONV_FUNCS, LIB2_DIVMOD_FUNCS, LIBGCC2_CFLAGS,
TARGET_LIBGCC2_CFLAGS.
Emit GTHREAD_FLAGS.
* libgcc2.c, libgcc2.h, gbl-ctors.h, longlong.h: Move to ../libgcc.
* config/darwin-64.c: Move to ../libgcc/config.
* config/divmod.c, config/floatunsidf.c, config/floatunsisf.c,
config/floatunsitf.c, config/floatunsixf.c, config/udivmod.c,
config/udivmodsi4.c: Move to ../libgcc/config.
* config/gthr-posix.c: Move to ../libgcc/config/alpha.
* config/memcmp.c, config/memcpy.c, config/memmove.c,
config/memset.c: Move to ../libgcc/config.
* config/t-darwin (TARGET_LIBGCC2_CFLAGS): Remove.
* config/t-freebsd: Remove.
* config/t-freebsd-thread: Move to ../libgcc/config.
* config/t-libgcc-pic: Move to ../libgcc/config.
* config/t-libunwind (TARGET_LIBGCC2_CFLAGS): Remove.
* config/t-linux: Remove.
* config/t-lynx (TARGET_LIBGCC2_CFLAGS, LIBGCC, INSTALL_LIBGCC):
Remove
* config/t-openbsd-thread: Move to ../libgcc/config.
* config/t-rtems (LIBGCC2_INCLUDES): Remove.
* config/t-sol2 (TARGET_LIBGCC2_CFLAGS): Remove.
* config/t-svr4: Remove.
* config/t-vxworks (LIBGCC, INSTALL_LIBGCC, TARGET_LIBGCC2_CFLAGS)
(LIBGCC2_DEBUG_CFLAGS, LIB2FUNCS_EXTRA, LIBGCC2_INCLUDES): Remove.
* config/vxlib.c, config/vxlib-tls.c: Move to ../libgcc/config.
* config/alpha/qrnnd.asm: Move to ../libgcc/config/alpha/qrnnd.S.
* config/alpha/t-alpha, config/alpha/t-ieee: Remove.
* config/alpha/t-vms (LIB2FUNCS_EXTRA, LIBGCC, INSTALL_LIBGCC):
Remove.
* config/alpha/vms-gcc_shell_handler.c: Move to ../libgcc/config/alpha.
* config/arm/bpabi.c, config/arm/unaligned-funcs.c,
config/arm/fp16.c, config/arm/linux-atomic.c,
config/arm/linux-atomic-64bit.c: Move to ../libgcc/config/arm.
* config/arm/t-arm-elf (LIBGCC, INSTALL_LIBGCC)
(TARGET_LIBGCC2_CFLAGS): Remove.
* config/arm/t-bpabi, config/arm/t-linux: Remove.
* config/arm/t-linux-eabi (TARGET_LIBGCC2_CFLAGS)
(LIB2FUNCS_STATIC_EXTRA): Remove.
* config/arm/t-netbsd: Remove.
* config/arm/t-strongarm-elf (LIBGCC, INSTALL_LIBGCC)
(TARGET_LIBGCC2_CFLAGS): Remove.
* config/arm/t-symbian (LIB2FUNCS_STATIC_EXTRA): Remove.
* config/arm/t-wince-pe (LIBGCC, INSTALL_LIBGCC)
(TARGET_LIBGCC2_CFLAGS): Remove.
* config/avr/t-avr (LIB2FUNCS_EXCLUDE, TARGET_LIBGCC2_CFLAGS)
(LIBGCC, INSTALL_LIBGCC): Remove.
* config/bfin/t-bfin-elf (TARGET_LIBGCC2_CFLAGS): Remove.
* config/bfin/t-bfin-linux: Likewise.
* config/bfin/t-bfin-uclinux: Likewise.
* config/c6x/eqd.c, config/c6x/eqf.c, config/c6x/ged.c,
config/c6x/gef.c, config/c6x/gtd.c, config/c6x/gtf.c,
config/c6x/led.c, config/c6x/lef.c, config/c6x/ltd.c,
config/c6x/ltf.c: Move to ../libgcc/config/c6x.
* config/c6x/t-c6x-elf (LIB2FUNCS_EXCLUDE, LIB2FUNCS_EXTRA):
Remove.
* config/c6x/t-c6x-uclinux (TARGET_LIBGCC2_CFLAGS): Remove.
* config/cris/arit.c: Move to ../libgcc/config/cris.
* config/cris/cris_abi_symbol.c: Remove.
* config/cris/cris.h: Remove obsolete comment.
* config/cris/mulsi3.asm: Move to ../libgcc/config/cris/mulsi3.S.
* config/cris/t-cris (LIB2FUNCS_EXTRA, CRIS_LIB1CSRC)
($(LIB2FUNCS_EXTRA)): Remove.
* config/cris/t-elfmulti (LIB2FUNCS_STATIC_EXTRA, INSTALL_LIBGCC)
(LIBGCC): Remove.
* config/cris/t-linux (TARGET_LIBGCC2_CFLAGS): Remove.
* config/fr30/t-fr30: Remove.
* config/frv/cmovd.c, config/frv/cmovh.c, config/frv/cmovw.c,
config/frv/modi.c, config/frv/uitod.c, config/frv/uitof.c,
config/frv/ulltod.c, config/frv/ulltof.c, config/frv/umodi.c: Move
to ../libgcc/config/frv.
* config/frv/t-frv (LIB2FUNCS_EXTRA, TARGET_LIBGCC2_CFLAGS)
(cmovh.c, cmovw.c, cmovd.c, modi.c, umodi.c, uitof.c, uitod.c)
(ulltof.c, LIBGCC, INSTALL_LIBGCC): Remove.
* config/frv/t-linux (TARGET_LIBGCC2_CFLAGS): Remove.
* config/h8300/clzhi2.c, config/h8300/ctzhi2.c,
config/h8300/fixunssfsi.c, config/h8300/parityhi2.c,
config/h8300/popcounthi2.c: Move to ../libgcc/config/h8300.
* config/h8300/t-h8300 (LIB2FUNCS_EXTRA, TARGET_LIBGCC2_CFLAGS)
(LIBGCC, INSTALL_LIBGCC): Remove.
* config/i386/gthr-win32.c: Move to ../libgcc/config/i386.
* config/i386/t-cygming (LIBGCC2_INCLUDES): Remove.
* config/i386/t-cygwin: Remove.
* config/i386/t-darwin (LIB2_SIDITI_CONV_FUNCS, LIB2FUNCS_EXTRA)
(LIB2FUNCS_EXCLUDE): Remove.
* config/i386/t-darwin64 (LIB2_SIDITI_CONV_FUNCS, LIB2FUNCS_EXTRA)
(LIBGCC, INSTALL_LIBGCC): Remove.
* config/i386/t-gthr-win32: Move to ../libgcc/config/i386.
* config/i386/t-linux64 (LIBGCC, INSTALL_LIBGCC): Remove.
* config/i386/t-mingw-w32: Likewise.
* config/i386/t-mingw-w64: Likewise.
* config/i386/t-openbsd: Likewise.
* config/i386/t-nto: Remove.
* config/ia64/quadlib.c: Move to ../libgcc/config/ia64.
* config/ia64/t-hpux (LIBGCC, INSTALL_LIBGCC, LIB2FUNCS_EXTRA)
(quadlib.c): Remove.
* config/ia64/t-ia64: Remove comment.
* config/iq2000/lib2extra-funcs.c: Move to
../libgcc/config/iq2000/lib2funcs.c.
* config/iq2000/t-iq2000: Remove.
* config/m32c/m32c-lib2.c: Move to ../libgcc/config/m32c/lib2funcs.c.
* config/m32c/m32c-lib2-trapv.c: Move to ../libgcc/config/m32c/trapv.c.
* config/m32r/t-linux (TARGET_LIBGCC2_CFLAGS): Remove.
* config/m32c/t-m32c (LIB2FUNCS_EXTRA): Remove.
* config/m32r/t-m32r (TARGET_LIBGCC2_CFLAGS, LIBGCC)
(INSTALL_LIBGCC): Remove.
* config/m68k/fpgnulib.c: Move to ../libgcc/config/m68k.
* config/m68k/t-floatlib: Remove.
* config/m68k/t-mlibs (LIBGCC, INSTALL_LIBGCC): Remove.
* config/mcore/t-mcore (TARGET_LIBGCC2_CFLAGS): Remove.
Fix typo.
(LIBGCC, INSTALL_LIBGCC): Remove.
* config/mep/mep-lib2.c: Move to ../libgcc/config/mep/lib2funcs.c.
* config/mep/mep-tramp.c: Move to ../libgcc/config/mep/tramp.c.
* config/mep/t-mep (LIB2FUNCS_EXTRA): Remove.
* config/mips/t-elf (TARGET_LIBGCC2_CFLAGS, LIBGCC)
(INSTALL_LIBGCC): Remove.
* config/mips/t-isa3264: Likewise.
* config/mips/t-mips (LIB2_SIDITI_CONV_FUNCS): Remove.
* config/mips/t-r3900 (TARGET_LIBGCC2_CFLAGS, LIBGCC)
(INSTALL_LIBGCC): Remove.
* config/mips/t-sde (LIBGCC, INSTALL_LIBGCC): Remove.
* config/mips/t-sr71k (TARGET_LIBGCC2_CFLAGS, LIBGCC)
(INSTALL_LIBGCC): Remove.
* config/mips/t-vr (TARGET_LIBGCC2_CFLAGS)
(LIB2FUNCS_STATIC_EXTRA): Remove.
* config/mips/vr4120-div.S: Move to ../libgcc/config/mips.
* config/mmix/t-mmix (TARGET_LIBGCC2_CFLAGS): Remove.
* config/mn10300/t-mn10300 (LIBGCC, INSTALL_LIBGCC): Remove.
* config/pa/fptr.c, config/pa/linux-atomic.c: Move to
../libgcc/config/pa.
* config/pa/lib2funcs.asm: Move to ../libgcc/config/pa/lib2funcs.S.
* config/pa/quadlib.c: Move to ../libgcc/config/pa.
* config/pa/t-dce-thr (LIBGCC, INSTALL_LIBGCC): Remove.
* config/pa/t-linux, config/pa/t-linux64: Remove.
* config/pa/t-pa-hpux, config/pa/t-pa-hpux10,
config/pa/t-pa-hpux11, config/pa/t-pa64: Remove.
* config/pdp11/t-pdp11 (TARGET_LIBGCC2_CFLAGS, LIB2FUNCS_EXTRA):
Remove.
* config/picochip/libgccExtras: Move to ../libgcc/config/picochip.
* config/picochip/t-picochip (LIB2FUNCS_EXTRA, RANLIB_FOR_TARGET)
(TARGET_LIBGCC2_CFLAGS, LIBGCC2_DEBUG_CFLAGS): Remove.
* config/rs6000/crtresfpr.asm: Move to
../libgcc/config/rs6000/crtresfpr.S.
* config/rs6000/crtresgpr.asm: Move to
../libgcc/config/rs6000/crtresgpr.S.
* config/rs6000/crtresxfpr.asm: Move to
../libgcc/config/rs6000/crtresxfpr.S.
* config/rs6000/crtresxgpr.asm: Move to
../libgcc/config/rs6000/crtresxgpr.S.
* config/rs6000/crtsavfpr.asm: Move to
../libgcc/config/rs6000/crtsavfpr.S.
* config/rs6000/crtsavgpr.asm: Move to
../libgcc/config/rs6000/crtsavgpr.S.
* config/rs6000/darwin-asm.h: Move to ../libgcc/config/rs6000.
* config/rs6000/darwin-fpsave.asm: Move to
../libgcc/config/rs6000/darwin-fpsave.S.
* config/rs6000/darwin-gpsave.asm: Move to
../libgcc/config/rs6000/darwin-gpsave.S.
* config/rs6000/darwin-tramp.asm: Move to
../libgcc/config/rs6000/darwin-tramp.S.
* config/rs6000/darwin-vecsave.asm: Move to
../libgcc/config/rs6000/darwin-vecsave.S.
* config/rs6000/darwin-world.asm: Move to
../libgcc/config/rs6000/darwin-world.S.
* config/rs6000/e500crtres32gpr.asm: Move to
../libgcc/config/rs6000/e500crtres32gpr.S.
* config/rs6000/e500crtres64gpr.asm: Move to
../libgcc/config/rs6000/e500crtres64gpr.S.
* config/rs6000/e500crtres64gprctr.asm: Move to
../libgcc/config/rs6000/e500crtres64gprctr.S.
* config/rs6000/e500crtrest32gpr.asm: Move to
../libgcc/config/rs6000/e500crtrest32gpr.S.
* config/rs6000/e500crtrest64gpr.asm: Move to
../libgcc/config/rs6000/e500crtrest64gpr.S.
* config/rs6000/e500crtresx32gpr.asm: Move to
../libgcc/config/rs6000/e500crtresx32gpr.S.
* config/rs6000/e500crtresx64gpr.asm: Move to
../libgcc/config/rs6000/e500crtresx64gpr.S.
* config/rs6000/e500crtsav32gpr.asm: Move to
../libgcc/config/rs6000/e500crtsav32gpr.S.
* config/rs6000/e500crtsav64gpr.asm: Move to
../libgcc/config/rs6000/e500crtsav64gpr.S.
* config/rs6000/e500crtsav64gprctr.asm: Move to
../libgcc/config/rs6000/e500crtsav64gprctr.S.
* config/rs6000/e500crtsavg32gpr.asm: Move to
../libgcc/config/rs6000/e500crtsavg32gpr.S.
* config/rs6000/e500crtsavg64gpr.asm: Move to
../libgcc/config/rs6000/e500crtsavg64gpr.S.
* config/rs6000/e500crtsavg64gprctr.asm: Move to
../libgcc/config/rs6000/e500crtsavg64gprctr.S.
* config/rs6000/eabi.asm: Move to ../libgcc/config/rs6000/eabi.S.
* config/rs6000/t-aix43 (LIBGCC, INSTALL_LIBGCC, LIB2FUNCS_EXTRA)
(TARGET_LIBGCC2_CFLAGS): Remove.
* config/rs6000/t-aix52: Likewise.
* config/rs6000/t-darwin: Remove.
* config/rs6000/t-darwin64 (LIB2_SIDITI_CONV_FUNCS)
(LIB2FUNCS_EXTRA): Remove.
* config/rs6000/t-fprules (LIBGCC, INSTALL_LIBGCC): Remove.
* config/rs6000/t-linux64 (TARGET_LIBGCC2_CFLAGS): Remove.
* config/rs6000/t-lynx (LIB2FUNCS_EXTRA, tramp.S, LIBGCC)
(INSTALL_LIBGCC): Remove.
* config/rs6000/t-netbsd (LIB2FUNCS_EXTRA)
(LIB2FUNCS_STATIC_EXTRA, tramp.S, crtsavfpr.S, crtresfpr.S)
(crtsavgpr.S, crtresgpr.S, crtresxfpr.S, crtresxgpr.S, LIBGCC)
(INSTALL_LIBGCC, $(T)crtsavfpr$(objext), $(T)crtresfpr$(objext))
(($(T)crtsavgpr$(objext), $(T)crtresgpr$(objext),
$(T)crtresxfpr$(objext), $(T)crtresxgpr$(objext)): Remove.
* config/rs6000/t-ppccomm (LIB2FUNCS_EXTRA)
(LIB2FUNCS_STATIC_EXTRA, eabi.S, tramp.S): Remove.
* config/rs6000/t-spe (LIBGCC, INSTALL_LIBGCC): Remove.
* config/rs6000/t-vxworks: Remove comment.
* config/rs6000/tramp.asm: Move to ../libgcc/config/rs6000/tramp.S.
* config/rx/t-rx (LIBGCC, INSTALL_LIBGCC): Remove.
* config/sh/linux-atomic.asm: Move to
../libgcc/config/sh/linux-atomic.S.
* config/sh/t-linux (LIB2FUNCS_EXTRA): Remove.
* config/sh/t-netbsd: Remove.
* config/sh/t-sh (TARGET_LIBGCC2_CFLAGS, LIBGCC, INSTALL_LIBGCC):
Remove.
* config/sparc/t-elf (LIBGCC, INSTALL_LIBGCC): Remove.
* config/sparc/t-leon: Likewise.
* config/sparc/t-leon3: Likewise.
* config/sparc/t-linux64: Likewise.
* config/sparc/t-netbsd64: Fix typo.
Remove comment.
* config/spu/divmodti4.c, config/spu/divv2df3.c,
config/spu/float_disf.c, config/spu/float_unsdidf.c,
config/spu/float_unsdisf.c, config/spu/float_unssidf.c,
config/spu/mfc_multi_tag_release.c,
config/spu/mfc_multi_tag_reserve.c, config/spu/mfc_tag_release.c,
config/spu/mfc_tag_reserve.c, config/spu/mfc_tag_table.c,
config/spu/multi3.c: Move to ../libgcc/config/spu.
* config/spu/t-spu-elf (TARGET_LIBGCC2_CFLAGS, LIB2FUNCS_EXCLUDE)
(LIB2FUNCS_STATIC_EXTRA, LIB2_SIDITI_CONV_FUNCS, LIBGCC)
(INSTALL_LIBGCC): Remove.
* config/stormy16/stormy16-lib2.c: Move to
../libgcc/config/stormy16/lib2.c.
* config/stormy16/stormy16-lib2-ashlsi3.c: Move to
../libgcc/config/stormy16/ashlsi3.c.
* config/stormy16/stormy16-lib2-ashrsi3.c: Move to
../libgcc/config/stormy16/ashrsi3.c.
* config/stormy16/stormy16-lib2-clzhi2.c: Move to
../libgcc/config/stormy16/clzhi2.c.
* config/stormy16/stormy16-lib2-cmpsi2.c: Move to
../libgcc/config/stormy16/cmpsi2.c.
* config/stormy16/stormy16-lib2-ctzhi2.c: Move to
../libgcc/config/stormy16/ctzhi2.c.
* config/stormy16/stormy16-lib2-divsi3.c: Move to
../libgcc/config/stormy16/divsi3.c.
* config/stormy16/stormy16-lib2-ffshi2.c: Move to
../libgcc/config/stormy16/ffshi2.c.
* config/stormy16/stormy16-lib2-lshrsi3.c: Move to
../libgcc/config/stormy16/lshrsi3.c.
* config/stormy16/stormy16-lib2-modsi3.c: Move to
../libgcc/config/stormy16/modsi3.c.
* config/stormy16/stormy16-lib2-parityhi2.c: Move to
../libgcc/config/stormy16/parityhi2.c.
* config/stormy16/stormy16-lib2-popcounthi2.c: Move to
../libgcc/config/stormy16/popcounthi2.c.
* config/stormy16/stormy16-lib2-ucmpsi2.c: Move to
../libgcc/config/stormy16/ucmpsi2.c.
* config/stormy16/stormy16-lib2-udivmodsi4.c: Move to
../libgcc/config/stormy16/udivmodsi4.c.
* config/stormy16/stormy16-lib2-udivsi3.c: Move to
../libgcc/config/stormy16/udivsi3.c.
* config/stormy16/stormy16-lib2-umodsi3.c: Move to
../libgcc/config/stormy16/umodsi3.c.
* config/stormy16/t-stormy16: Move to ../libgcc/config/t-stormy16.
* config/v850/t-v850 (INSTALL_LIBGCC): Remove.
* config/xtensa/lib2funcs.S: Move to ../libgcc/config/xtensa.
* config/xtensa/t-elf: Remove.
* config/xtensa/t-xtensa (LIB2FUNCS_EXTRA): Remove.
* config.gcc (*-*-freebsd*): Remove t-freebsd, t-freebsd-thread
from tmake_file.
(*-*-linux*, frv-*-*linux*, *-*-kfreebsd*-gnu, *-*-knetbsd*-gnu,
*-*-gnu*, *-*-kopensolaris*-gnu): Remove t-linux from tmake_file.
(*-*-netbsd*): Remove t-libgcc-pic from tmake_file.
(*-*-openbsd*): Likewise.
Remove t-openbsd-thread for posix threads.
(alpha*-*-linux*): Remove alpha/t-alpha, alpha/t-ieee
from tmake_file.
(alpha*-*-freebsd*): Likewise.
(alpha*-*-netbsd*): Likewise.
(alpha*-*-openbsd*): Likewise.
(alpha64-dec-*vms*): Likewise.
(alpha*-dec-*vms*): Likewise.
(arm*-*-netbsdelf*): Remove arm/t-netbsd from tmake_file.
(arm*-*-linux*): Remove t-linux from tmake_file.
Remove arm/t-bpabi from tmake_file for arm*-*-linux-*eabi.
(arm*-*-uclinux*): Remove arm/t-bpabi from tmake_file for
arm*-*-uclinux*eabi.
(arm*-*-eabi*, arm*-*-symbianelf* ): Remove arm/t-bpabi from
tmake_file for arm*-*-eabi*.
(fr30-*-elf): Remove tmake_file.
(hppa*64*-*-linux*): Remove tmake_file.
(hppa*-*-linux*): Likewise.
(hppa[12]*-*-hpux10*): Remove pa/t-pa-hpux10, pa/t-pa-hpux from
tmake_file.
(hppa*64*-*-hpux11*): Remove pa/t-pa64, pa/t-pa-hpux from tmake_file.
(hppa[12]*-*-hpux11*): Remove pa/t-pa-hpux11, pa/t-pa-hpux from
tmake_file.
(i[34567]86-*-elf*): Remove tmake_file.
(x86_64-*-elf*): Likewise.
(i[34567]86-*-nto-qnx*): Likewise.
(i[34567]86-*-cygwin*): Remove i386/t-cygwin from tmake_file.
(i[34567]86-*-mingw*, x86_64-*-mingw*): Remove i386/t-gthr-win32
from tmake_file if using win32 threads.
(iq2000*-*-elf*): Remove tmake-file.
(microblaze*-linux*): Likewise.
(sh-*-elf*, sh[12346l]*-*-elf*, sh-*-linux*)
(sh[2346lbe]*-*-linux*, sh-*-netbsdelf*, shl*-*-netbsdelf*)
(sh5-*-netbsd*, sh5l*-*-netbsd*, sh64-*-netbsd*)
(sh64l*-*-netbsd*): Remove sh/t-netbsd from tmake_file for
sh5*-*-netbsd*, sh64*-netbsd*, *-*-netbsd.
(xtensa*-*-elf*): Remove tmake_file.
gcc/po:
* EXCLUDES (config/vxlib.c, gbl-ctors.h, libgcc2.c, libgcc2.h)
(longlong.h): Remove.
libgcc:
* configure.ac: Include ../config/picflag.m4.
(GCC_PICFLAG): Call it.
Substitute.
* configure: Regenerate.
* Makefile.in (gcc_srcdir): Remove.
(LIBGCC2_DEBUG_CFLAGS, LIBGCC2_CFLAGS, LIBGCC2_INCLUDES)
(HOST_LIBGCC2_CFLAGS, PICFLAG, LIB2FUNCS_ST, LIB2FUNCS_EXCLUDE)
(LIB2_DIVMOD_FUNCS, LIB2ADD, LIB2ADD_ST): Set.
($(lib2funcs-o), $(lib2funcs-s-o), $(lib2-divmod-o))
($(lib2-divmod-s-o)): Use $(srcdir) to refer to libgcc2.c.
Use $<.
Remove comment.
* libgcc2.c, libgcc2.h, gbl-ctors.h, longlong.h: New files.
* siditi-object.mk ($o$(objext), $(o)_s$(objext)): Use $(srcdir)
to refer to libgcc2.c.
Use $<.
* config/darwin-64.c: New file.
* config/darwin-crt3.c: Remove comment.
* config/divmod.c, config/floatunsidf.c, config/floatunsisf.c,
config/floatunsitf.c, config/floatunsixf.c, config/udivmod.c,
config/udivmodsi4.c: New files.
* config/memcmp.c, config/memcpy.c, config/memmove.c,
config/memset.c: New files.
* config/t-crtstuff-pic (CRTSTUFF_T_CFLAGS_S): Use $(PICFLAG).
* config/t-darwin (HOST_LIBGCC2_CFLAGS): Set.
* config/t-freebsd-thread, config/t-libgcc-pic: New files.
* config/t-libunwind (HOST_LIBGCC2_CFLAGS): Set.
* config/t-openbsd-thread: New file.
* config/t-sol2 (HOST_LIBGCC2_CFLAGS): Remove.
* config/t-vxworks, config/vxlib-tls.c, config/vxlib.c: New files.
* config/alpha/gthr-posix.c, config/alpha/qrnnd.S: New files.
* config/alpha/t-alpha (LIB2ADD): Use $(srcdir) to refer to
qrnnd.S.
Adapt filename.
* config/alpha/t-osf-pthread (LIB2ADD): Use $(srcdir)/config/alpha
to refer to gthr-posix.c.
* config/alpha/t-vms (LIB2ADD): Set.
* config/alpha/vms-gcc_shell_handler.c: New file.
* config/arm/bpabi.c, config/arm/fp16.c,
config/arm/linux-atomic.c, config/arm/linux-atomic-64bit.c,
config/arm/unaligned-funcs.c: New files.
* config/arm/t-bpabi (LIB2ADD, LIB2ADD_ST): Set.
* config/arm/t-elf (HOST_LIBGCC2_CFLAGS): Set.
* config/arm/t-linux: Likewise.
* config/arm/t-linux-eabi (LIB2ADD_ST): Add.
* config/arm/t-netbsd: New file.
* config/arm/t-strongarm-elf (HOST_LIBGCC2_CFLAGS): Set.
* config/arm/t-symbian (LIB2ADD_ST): Set.
* config/avr/t-avr (LIB2FUNCS_EXCLUDE, HOST_LIBGCC2_CFLAGS): Set.
* config/bfin/t-crtstuff (CRTSTUFF_T_CFLAGS): Use $(PICFLAG).
* config/bfin/t-elf: New file.
* config/c6x/eqd.c, config/c6x/eqf.c, config/c6x/ged.c,
config/c6x/gef.c, config/c6x/gtd.c, config/c6x/gtf.c,
config/c6x/led.c, config/c6x/lef.c, config/c6x/ltd.c,
config/c6x/ltf.c: New files.
* config/c6x/t-elf (LIB2FUNCS_EXCLUDE, LIB2ADD)
(HOST_LIBGCC2_CFLAGS): Set.
* config/c6x/t-uclinux (HOST_LIBGCC2_CFLAGS): Set.
(CRTSTUFF_T_CFLAGS): Use $(PICFLAG).
* config/cris/arit.c, config/cris/mulsi3.S, config/cris/t-cris:
New files.
* config/cris/t-elfmulti (LIB2ADD_ST): Set.
* config/cris/t-linux (HOST_LIBGCC2_CFLAGS): Remove.
* config/frv/cmovd.c, config/frv/cmovh.c, config/frv/cmovw.c,
config/frv/modi.c, config/frv/uitod.c, config/frv/uitof.c,
config/frv/ulltod.c, config/frv/ulltof.c, config/frv/umodi.c: New
files.
* config/frv/t-frv (LIB2ADD): Set.
* config/frv/t-linux (CRTSTUFF_T_CFLAGS): Use $(PICFLAG).
* config/h8300/clzhi2.c, config/h8300/ctzhi2.c,
config/h8300/fixunssfsi.c, config/h8300/parityhi2.c,
config/h8300/popcounthi2.c: New files.
* config/h8300/t-h8300 (LIB2ADD, HOST_LIBGCC2_CFLAGS): Set.
* config/i386/gthr-win32.c: New file.
* config/i386/t-cygming (LIBGCC2_INCLUDES): Set.
* config/i386/t-cygwin: Likewise.
* config/i386/t-darwin, config/i386/t-darwin64,
config/i386/t-gthr-win32, config/i386/t-interix: New files.
* config/i386/t-nto (HOST_LIBGCC2_CFLAGS): Set.
(CRTSTUFF_T_CFLAGS): Use $(PICFLAG).
* config/i386/t-sol2 (CRTSTUFF_T_CFLAGS): Use $(PICFLAG).
* config/ia64/quadlib.c: New file.
* config/ia64/t-hpux (LIB2ADD): Set.
* config/ia64/t-ia64: Add comment.
* config/iq2000/lib2funcs.c, config/iq2000/t-iq2000: New files.
* config/lm32/t-uclinux (CRTSTUFF_T_CFLAGS): Use $(PICFLAG).
(HOST_LIBGCC2_CFLAGS): Append, remove -fPIC.
* config/m32c/lib2funcs.c, config/m32c/trapv.c: New files.
* config/m32c/t-m32c (LIB2ADD): Set.
* config/m32r/t-linux (HOST_LIBGCC2_CFLAGS): Set.
* config/m32r/t-m32r: Likewise.
* config/m68k/fpgnulib.c: New file.
* config/m68k/t-floatlib (LIB2ADD): Set.
(xfgnulib.c): New target.
* config/mcore/t-mcore (HOST_LIBGCC2_CFLAGS): Set.
* config/mep/lib2funcs.c, config/mep/tramp.c: New files.
* config/mep/t-mep (LIB2ADD): Set.
* config/microblaze/divsi3.asm: Rename to divsi3.S.
* config/microblaze/moddi3.asm: Rename to moddi3.S.
* config/microblaze/modsi3.asm: Rename to modsi3.S.
* config/microblaze/muldi3_hard.asm: Rename to hard.S.
* config/microblaze/mulsi3.asm: Rename to mulsi3.S.
* config/microblaze/stack_overflow_exit.asm: Rename to exit.S.
* config/microblaze/udivsi3.asm: Rename to udivsi3.S.
* config/microblaze/umodsi3.asm: Rename to umodsi3.S.
* config/microblaze/t-microblaze (LIB2ADD): Reflect this.
* config/mips/t-elf, config/mips/t-vr, config/mips/vr4120-div.S:
New files.
* config/mips/t-mips (LIB2_SIDITI_CONV_FUNCS): Set.
* config/mmix/t-mmix (HOST_LIBGCC2_CFLAGS): Set.
* config/pa/fptr.c, config/pa/lib2funcs.S,
config/pa/linux-atomic.c, config/pa/quadlib.c: New files.
* config/pa/t-linux (HOST_LIBGCC2_CFLAGS): Set.
(LIB2ADD, LIB2ADD_ST): Set.
* config/pa/t-hpux, config/pa/t-hpux10, config/pa/t-pa64: New files.
* config/pa/t-linux (HOST_LIBGCC2_CFLAGS, LIB2ADD, LIB2ADD_ST):
Set.
* config/pa/t-linux64 (LIB2ADD_ST, HOST_LIBGCC2_CFLAGS): Set.
* config/pdp11/t-pdp11: New file.
* config/picochip/libgccExtras/adddi3.S,
config/picochip/libgccExtras/ashlsi3.S,
config/picochip/libgccExtras/ashrsi3.S,
config/picochip/libgccExtras/clzsi2.S,
config/picochip/libgccExtras/cmpsi2.S,
config/picochip/libgccExtras/divmod15.S,
config/picochip/libgccExtras/divmodhi4.S,
config/picochip/libgccExtras/divmodsi4.S,
config/picochip/libgccExtras/lshrsi3.S,
config/picochip/libgccExtras/parityhi2.S,
config/picochip/libgccExtras/popcounthi2.S,
config/picochip/libgccExtras/subdi3.S,
config/picochip/libgccExtras/ucmpsi2.S,
config/picochip/libgccExtras/udivmodhi4.S,
config/picochip/libgccExtras/udivmodsi4.S: New files.
* config/picochip/t-picochip (LIB2ADD, HOST_LIBGCC2_CFLAGS)
(LIBGCC2_DEBUG_CFLAGS, RANLIB_FOR_TARGET): Set.
* config/rs6000/crtresfpr.S, config/rs6000/crtresgpr.S,
config/rs6000/crtresxfpr.S, config/rs6000/crtresxgpr.S,
config/rs6000/crtsavfpr.S, config/rs6000/crtsavgpr.S)
config/rs6000/darwin-asm.h, config/rs6000/darwin-fpsave.S,
config/rs6000/darwin-gpsave.S, config/rs6000/darwin-tramp.S,
config/rs6000/darwin-vecsave.S, config/rs6000/darwin-world.S: New
files.
* config/rs6000/t-darwin (LIB2ADD, LIB2ADD_ST)
(HOST_LIBGCC2_CFLAGS): Set.
* config/rs6000/t-darwin64: New file.
* config/rs6000/t-linux64 (HOST_LIBGCC2_CFLAGS): Set.
* config/rs6000/t-lynx, config/rs6000/t-netbsd: New files.
* config/rs6000/t-ppccomm (LIB2ADD): Add
$(srcdir)/config/rs6000/tramp.S.
(LIB2ADD_ST): Use $(srcdir)/config/rs6000 to refer to sources.
Add $(srcdir)/config/rs6000/eabi.S.
(crtsavfpr.S, crtresfpr.S, crtsavgpr.S, crtresgpr.S, crtresxfpr.S)
(crtresxgpr.S, e500crtres32gpr.S, e500crtres64gpr.S)
(e500crtres64gprctr.S, e500crtrest32gpr.S, e500crtrest64gpr.S)
(e500crtresx32gpr.S, e500crtresx64gpr.S, e500crtsav32gpr.S)
(e500crtsav64gpr.S, e500crtsav64gprctr.S, e500crtsavg32gpr.S)
(e500crtsavg64gpr.S, e500crtsavg64gprctr.S): Remove.
* config/rs6000/tramp.S: New file.
* config/s390/t-tpf: Remove.
* config/sh/linux-atomic.S: New file.
* config/sh/t-linux (LIB2ADD): Set.
(HOST_LIBGCC2_CFLAGS): Append, remove -fpic.
* config/sh/t-netbsd (LIB2ADD, HOST_LIBGCC2_CFLAGS): Set.
* config/sh/t-sh (unwind-dw2-Os-4-200.o): Use $(srcdir) to refer
to unwind-dw2.c.
(HOST_LIBGCC2_CFLAGS): Set.
* config/sparc/t-sol2 (CRTSTUFF_T_CFLAGS): Use $(PICFLAG).
* config/spu/divmodti4.c, config/spu/divv2df3.c,
config/spu/float_disf.c, config/spu/float_unsdidf.c,
config/spu/float_unsdisf.c, config/spu/float_unssidf.c,
config/spu/mfc_multi_tag_release.c,
config/spu/mfc_multi_tag_reserve.c, config/spu/mfc_tag_release.c,
config/spu/mfc_tag_reserve.c, config/spu/mfc_tag_table.c,
config/spu/multi3.c: New files.
* config/spu/t-elf (LIB2ADD, LIB2ADD_ST, LIB2_SIDITI_CONV_FUNCS)
(HOST_LIBGCC2_CFLAGS): Set.
* config/stormy16/ashlsi3.c, config/stormy16/ashrsi3.c,
config/stormy16/clzhi2.c, config/stormy16/cmpsi2.c,
config/stormy16/ctzhi2.c, config/stormy16/divsi3.c,
config/stormy16/ffshi2.c, config/stormy16/lib2.c,
config/stormy16/lshrsi3.c, config/stormy16/modsi3.c,
config/stormy16/parityhi2.c, config/stormy16/popcounthi2.c,
config/stormy16/t-stormy16, config/stormy16/ucmpsi2.c,
config/stormy16/udivmodsi4.c, config/stormy16/udivsi3.c,
config/stormy16/umodsi3.c: New files.
* config/xtensa/lib2funcs.S: New file.
* config/xtensa/t-elf (HOST_LIBGCC2_CFLAGS): Set.
* config/xtensa/t-xtensa (LIB2ADD): Set.
* config.host (*-*-darwin*): Add t-libgcc-pic to tmake_file.
(*-*-freebsd*): Add t-freebsd, t-libgcc-pic to tmake_file.
Add t-freebsd-thread to tmake_file for posix threads.
(*-*-linux*, frv-*-*linux*, *-*-kfreebsd*-gnu, *-*-knetbsd*-gnu)
(*-*-gnu*, *-*-kopensolaris*-gnu): Add t-libgcc-pic to tmake_file.
(*-*-lynxos*): Likewise.
(*-*-netbsd*): Likewise.
(*-*-openbsd*): Likewise.
Add t-openbsd-thread to tmake_file for posix threads.
(*-*-solaris2*): Add t-libgcc-pic to tmake_file.
(*-*-vxworks*): Set tmake_file.
(alpha*-*-linux*): Add alpha/t-alpha, alpha/t-ieee to tmake_file.
(alpha*-*-freebsd*): Likewise.
(alpha*-*-netbsd*): Likewise.
(alpha*-*-openbsd*): Likewise.
(alpha*-dec-osf5.1*): Remove qrnnd.o, gthr-posix.o from extra_parts.
(alpha64-dec-*vms*): Add alpha/t-alpha, alpha/t-ieee to tmake_file.
(alpha*-dec-*vms*): Likewise.
(arm*-*-netbsdelf*): Add arm/t-netbsd to tmake_file.
(bfin*-elf*): Add bfin/t-elf to tmake_file.
(bfin*-uclinux*): Likewise.
(bfin*-linux-uclibc*): Likewise.
(crisv32-*-elf): Add cris/t-cris to tmake_file.
(crisv32-*-none): Likewise.
(cris-*-elf): Likewise.
(cris-*-none): Likewise.
(cris-*-linux*, crisv32-*-linux*): Likewise.
(hppa[12]*-*-hpux10*): Add pa/t-hpux pa/t-hpux10, t-libgcc-pic to
tmake_file.
(hppa*64*-*-hpux11*): Add pa/t-hpux, pa/t-pa64, t-libgcc-pic to
tmake_file.
(hppa[12]*-*-hpux11*): Add pa/t-hpux, t-libgcc-pic to tmake_file.
(i[34567]86-*-elf*): Add t-libgcc-pic to tmake_file.
(x86_64-*-elf*): Likewise.
(i[34567]86-*-nto-qnx*): Likewise.
(i[34567]86-*-mingw*): Add i386/t-gthr-win32 to tmake_file for
win32 threads.
(x86_64-*-mingw*): Likewise.
(i[34567]86-*-interix3*): Add i386/t-interix to tmake_file.
(lm32-*-uclinux*): Add t-libgcc-pic to tmake_file.
(mipsisa32-*-elf*, mipsisa32el-*-elf*, mipsisa32r2-*-elf*)
(mipsisa32r2el-*-elf*, mipsisa64-*-elf*, mipsisa64el-*-elf*)
(mipsisa64r2-*-elf*, mipsisa64r2el-*-elf*): Add mips/t-elf to
tmake_file.
(mipsisa64sr71k-*-elf*): Likewise.
(mipsisa64sb1-*-elf*, mipsisa64sb1el-*-elf*): Likewise.
(mips-*-elf*, mipsel-*-elf*): Likewise.
(mips64-*-elf*, mips64el-*-elf*): Likewise.
(mips64orion-*-elf*, mips64orionel-*-elf*): Likewise.
(mips*-*-rtems*): Likewise.
(mips64vr-*-elf*, mips64vrel-*-elf*): Add mips/t-elf, mips/t-vr
to tmake_file.
(pdp11-*-*): Add pdp11/t-pdp11 to tmake_file.
(powerpc64-*-darwin*): Add rs6000/t-darwin64 to tmake_file.
(s390x-ibm-tpf*): Add t-libgcc-pic to tmake_file.
(spu-*-elf*): Likewise.
(tic6x-*-uclinux): Add t-libgcc-pic to tmake_file.
libquadmath:
* printf/gmp-impl.h: Adapt path to longlong.h.
From-SVN: r180774
Diffstat (limited to 'libgcc')
231 files changed, 19579 insertions, 265 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 6b2514a..deab941 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,5 +1,254 @@ 2011-11-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + * configure.ac: Include ../config/picflag.m4. + (GCC_PICFLAG): Call it. + Substitute. + * configure: Regenerate. + * Makefile.in (gcc_srcdir): Remove. + (LIBGCC2_DEBUG_CFLAGS, LIBGCC2_CFLAGS, LIBGCC2_INCLUDES) + (HOST_LIBGCC2_CFLAGS, PICFLAG, LIB2FUNCS_ST, LIB2FUNCS_EXCLUDE) + (LIB2_DIVMOD_FUNCS, LIB2ADD, LIB2ADD_ST): Set. + ($(lib2funcs-o), $(lib2funcs-s-o), $(lib2-divmod-o)) + ($(lib2-divmod-s-o)): Use $(srcdir) to refer to libgcc2.c. + Use $<. + Remove comment. + * libgcc2.c, libgcc2.h, gbl-ctors.h, longlong.h: New files. + * siditi-object.mk ($o$(objext), $(o)_s$(objext)): Use $(srcdir) + to refer to libgcc2.c. + Use $<. + * config/darwin-64.c: New file. + * config/darwin-crt3.c: Remove comment. + * config/divmod.c, config/floatunsidf.c, config/floatunsisf.c, + config/floatunsitf.c, config/floatunsixf.c, config/udivmod.c, + config/udivmodsi4.c: New files. + * config/memcmp.c, config/memcpy.c, config/memmove.c, + config/memset.c: New files. + * config/t-crtstuff-pic (CRTSTUFF_T_CFLAGS_S): Use $(PICFLAG). + * config/t-darwin (HOST_LIBGCC2_CFLAGS): Set. + * config/t-freebsd-thread, config/t-libgcc-pic: New files. + * config/t-libunwind (HOST_LIBGCC2_CFLAGS): Set. + * config/t-openbsd-thread: New file. + * config/t-sol2 (HOST_LIBGCC2_CFLAGS): Remove. + * config/t-vxworks, config/vxlib-tls.c, config/vxlib.c: New files. + * config/alpha/gthr-posix.c, config/alpha/qrnnd.S: New files. + * config/alpha/t-alpha (LIB2ADD): Use $(srcdir) to refer to + qrnnd.S. + Adapt filename. + * config/alpha/t-osf-pthread (LIB2ADD): Use $(srcdir)/config/alpha + to refer to gthr-posix.c. + * config/alpha/t-vms (LIB2ADD): Set. + * config/alpha/vms-gcc_shell_handler.c: New file. + * config/arm/bpabi.c, config/arm/fp16.c, + config/arm/linux-atomic.c, config/arm/linux-atomic-64bit.c, + config/arm/unaligned-funcs.c: New files. + * config/arm/t-bpabi (LIB2ADD, LIB2ADD_ST): Set. + * config/arm/t-elf (HOST_LIBGCC2_CFLAGS): Set. + * config/arm/t-linux: Likewise. + * config/arm/t-linux-eabi (LIB2ADD_ST): Add. + * config/arm/t-netbsd: New file. + * config/arm/t-strongarm-elf (HOST_LIBGCC2_CFLAGS): Set. + * config/arm/t-symbian (LIB2ADD_ST): Set. + * config/avr/t-avr (LIB2FUNCS_EXCLUDE, HOST_LIBGCC2_CFLAGS): Set. + * config/bfin/t-crtstuff (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). + * config/bfin/t-elf: New file. + * config/c6x/eqd.c, config/c6x/eqf.c, config/c6x/ged.c, + config/c6x/gef.c, config/c6x/gtd.c, config/c6x/gtf.c, + config/c6x/led.c, config/c6x/lef.c, config/c6x/ltd.c, + config/c6x/ltf.c: New files. + * config/c6x/t-elf (LIB2FUNCS_EXCLUDE, LIB2ADD) + (HOST_LIBGCC2_CFLAGS): Set. + * config/c6x/t-uclinux (HOST_LIBGCC2_CFLAGS): Set. + (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). + * config/cris/arit.c, config/cris/mulsi3.S, config/cris/t-cris: + New files. + * config/cris/t-elfmulti (LIB2ADD_ST): Set. + * config/cris/t-linux (HOST_LIBGCC2_CFLAGS): Remove. + * config/frv/cmovd.c, config/frv/cmovh.c, config/frv/cmovw.c, + config/frv/modi.c, config/frv/uitod.c, config/frv/uitof.c, + config/frv/ulltod.c, config/frv/ulltof.c, config/frv/umodi.c: New + files. + * config/frv/t-frv (LIB2ADD): Set. + * config/frv/t-linux (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). + * config/h8300/clzhi2.c, config/h8300/ctzhi2.c, + config/h8300/fixunssfsi.c, config/h8300/parityhi2.c, + config/h8300/popcounthi2.c: New files. + * config/h8300/t-h8300 (LIB2ADD, HOST_LIBGCC2_CFLAGS): Set. + * config/i386/gthr-win32.c: New file. + * config/i386/t-cygming (LIBGCC2_INCLUDES): Set. + * config/i386/t-cygwin: Likewise. + * config/i386/t-darwin, config/i386/t-darwin64, + config/i386/t-gthr-win32, config/i386/t-interix: New files. + * config/i386/t-nto (HOST_LIBGCC2_CFLAGS): Set. + (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). + * config/i386/t-sol2 (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). + * config/ia64/quadlib.c: New file. + * config/ia64/t-hpux (LIB2ADD): Set. + * config/ia64/t-ia64: Add comment. + * config/iq2000/lib2funcs.c, config/iq2000/t-iq2000: New files. + * config/lm32/t-uclinux (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). + (HOST_LIBGCC2_CFLAGS): Append, remove -fPIC. + * config/m32c/lib2funcs.c, config/m32c/trapv.c: New files. + * config/m32c/t-m32c (LIB2ADD): Set. + * config/m32r/t-linux (HOST_LIBGCC2_CFLAGS): Set. + * config/m32r/t-m32r: Likewise. + * config/m68k/fpgnulib.c: New file. + * config/m68k/t-floatlib (LIB2ADD): Set. + (xfgnulib.c): New target. + * config/mcore/t-mcore (HOST_LIBGCC2_CFLAGS): Set. + * config/mep/lib2funcs.c, config/mep/tramp.c: New files. + * config/mep/t-mep (LIB2ADD): Set. + * config/microblaze/divsi3.asm: Rename to divsi3.S. + * config/microblaze/moddi3.asm: Rename to moddi3.S. + * config/microblaze/modsi3.asm: Rename to modsi3.S. + * config/microblaze/muldi3_hard.asm: Rename to hard.S. + * config/microblaze/mulsi3.asm: Rename to mulsi3.S. + * config/microblaze/stack_overflow_exit.asm: Rename to exit.S. + * config/microblaze/udivsi3.asm: Rename to udivsi3.S. + * config/microblaze/umodsi3.asm: Rename to umodsi3.S. + * config/microblaze/t-microblaze (LIB2ADD): Reflect this. + * config/mips/t-elf, config/mips/t-vr, config/mips/vr4120-div.S: + New files. + * config/mips/t-mips (LIB2_SIDITI_CONV_FUNCS): Set. + * config/mmix/t-mmix (HOST_LIBGCC2_CFLAGS): Set. + * config/pa/fptr.c, config/pa/lib2funcs.S, + config/pa/linux-atomic.c, config/pa/quadlib.c: New files. + * config/pa/t-linux (HOST_LIBGCC2_CFLAGS): Set. + (LIB2ADD, LIB2ADD_ST): Set. + * config/pa/t-hpux, config/pa/t-hpux10, config/pa/t-pa64: New files. + * config/pa/t-linux (HOST_LIBGCC2_CFLAGS, LIB2ADD, LIB2ADD_ST): + Set. + * config/pa/t-linux64 (LIB2ADD_ST, HOST_LIBGCC2_CFLAGS): Set. + * config/pdp11/t-pdp11: New file. + * config/picochip/libgccExtras/adddi3.S, + config/picochip/libgccExtras/ashlsi3.S, + config/picochip/libgccExtras/ashrsi3.S, + config/picochip/libgccExtras/clzsi2.S, + config/picochip/libgccExtras/cmpsi2.S, + config/picochip/libgccExtras/divmod15.S, + config/picochip/libgccExtras/divmodhi4.S, + config/picochip/libgccExtras/divmodsi4.S, + config/picochip/libgccExtras/lshrsi3.S, + config/picochip/libgccExtras/parityhi2.S, + config/picochip/libgccExtras/popcounthi2.S, + config/picochip/libgccExtras/subdi3.S, + config/picochip/libgccExtras/ucmpsi2.S, + config/picochip/libgccExtras/udivmodhi4.S, + config/picochip/libgccExtras/udivmodsi4.S: New files. + * config/picochip/t-picochip (LIB2ADD, HOST_LIBGCC2_CFLAGS) + (LIBGCC2_DEBUG_CFLAGS, RANLIB_FOR_TARGET): Set. + * config/rs6000/crtresfpr.S, config/rs6000/crtresgpr.S, + config/rs6000/crtresxfpr.S, config/rs6000/crtresxgpr.S, + config/rs6000/crtsavfpr.S, config/rs6000/crtsavgpr.S) + config/rs6000/darwin-asm.h, config/rs6000/darwin-fpsave.S, + config/rs6000/darwin-gpsave.S, config/rs6000/darwin-tramp.S, + config/rs6000/darwin-vecsave.S, config/rs6000/darwin-world.S: New + files. + * config/rs6000/t-darwin (LIB2ADD, LIB2ADD_ST) + (HOST_LIBGCC2_CFLAGS): Set. + * config/rs6000/t-darwin64: New file. + * config/rs6000/t-linux64 (HOST_LIBGCC2_CFLAGS): Set. + * config/rs6000/t-lynx, config/rs6000/t-netbsd: New files. + * config/rs6000/t-ppccomm (LIB2ADD): Add + $(srcdir)/config/rs6000/tramp.S. + (LIB2ADD_ST): Use $(srcdir)/config/rs6000 to refer to sources. + Add $(srcdir)/config/rs6000/eabi.S. + (crtsavfpr.S, crtresfpr.S, crtsavgpr.S, crtresgpr.S, crtresxfpr.S) + (crtresxgpr.S, e500crtres32gpr.S, e500crtres64gpr.S) + (e500crtres64gprctr.S, e500crtrest32gpr.S, e500crtrest64gpr.S) + (e500crtresx32gpr.S, e500crtresx64gpr.S, e500crtsav32gpr.S) + (e500crtsav64gpr.S, e500crtsav64gprctr.S, e500crtsavg32gpr.S) + (e500crtsavg64gpr.S, e500crtsavg64gprctr.S): Remove. + * config/rs6000/tramp.S: New file. + * config/s390/t-tpf: Remove. + * config/sh/linux-atomic.S: New file. + * config/sh/t-linux (LIB2ADD): Set. + (HOST_LIBGCC2_CFLAGS): Append, remove -fpic. + * config/sh/t-netbsd (LIB2ADD, HOST_LIBGCC2_CFLAGS): Set. + * config/sh/t-sh (unwind-dw2-Os-4-200.o): Use $(srcdir) to refer + to unwind-dw2.c. + (HOST_LIBGCC2_CFLAGS): Set. + * config/sparc/t-sol2 (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). + * config/spu/divmodti4.c, config/spu/divv2df3.c, + config/spu/float_disf.c, config/spu/float_unsdidf.c, + config/spu/float_unsdisf.c, config/spu/float_unssidf.c, + config/spu/mfc_multi_tag_release.c, + config/spu/mfc_multi_tag_reserve.c, config/spu/mfc_tag_release.c, + config/spu/mfc_tag_reserve.c, config/spu/mfc_tag_table.c, + config/spu/multi3.c: New files. + * config/spu/t-elf (LIB2ADD, LIB2ADD_ST, LIB2_SIDITI_CONV_FUNCS) + (HOST_LIBGCC2_CFLAGS): Set. + * config/stormy16/ashlsi3.c, config/stormy16/ashrsi3.c, + config/stormy16/clzhi2.c, config/stormy16/cmpsi2.c, + config/stormy16/ctzhi2.c, config/stormy16/divsi3.c, + config/stormy16/ffshi2.c, config/stormy16/lib2.c, + config/stormy16/lshrsi3.c, config/stormy16/modsi3.c, + config/stormy16/parityhi2.c, config/stormy16/popcounthi2.c, + config/stormy16/t-stormy16, config/stormy16/ucmpsi2.c, + config/stormy16/udivmodsi4.c, config/stormy16/udivsi3.c, + config/stormy16/umodsi3.c: New files. + * config/xtensa/lib2funcs.S: New file. + * config/xtensa/t-elf (HOST_LIBGCC2_CFLAGS): Set. + * config/xtensa/t-xtensa (LIB2ADD): Set. + * config.host (*-*-darwin*): Add t-libgcc-pic to tmake_file. + (*-*-freebsd*): Add t-freebsd, t-libgcc-pic to tmake_file. + Add t-freebsd-thread to tmake_file for posix threads. + (*-*-linux*, frv-*-*linux*, *-*-kfreebsd*-gnu, *-*-knetbsd*-gnu) + (*-*-gnu*, *-*-kopensolaris*-gnu): Add t-libgcc-pic to tmake_file. + (*-*-lynxos*): Likewise. + (*-*-netbsd*): Likewise. + (*-*-openbsd*): Likewise. + Add t-openbsd-thread to tmake_file for posix threads. + (*-*-solaris2*): Add t-libgcc-pic to tmake_file. + (*-*-vxworks*): Set tmake_file. + (alpha*-*-linux*): Add alpha/t-alpha, alpha/t-ieee to tmake_file. + (alpha*-*-freebsd*): Likewise. + (alpha*-*-netbsd*): Likewise. + (alpha*-*-openbsd*): Likewise. + (alpha*-dec-osf5.1*): Remove qrnnd.o, gthr-posix.o from extra_parts. + (alpha64-dec-*vms*): Add alpha/t-alpha, alpha/t-ieee to tmake_file. + (alpha*-dec-*vms*): Likewise. + (arm*-*-netbsdelf*): Add arm/t-netbsd to tmake_file. + (bfin*-elf*): Add bfin/t-elf to tmake_file. + (bfin*-uclinux*): Likewise. + (bfin*-linux-uclibc*): Likewise. + (crisv32-*-elf): Add cris/t-cris to tmake_file. + (crisv32-*-none): Likewise. + (cris-*-elf): Likewise. + (cris-*-none): Likewise. + (cris-*-linux*, crisv32-*-linux*): Likewise. + (hppa[12]*-*-hpux10*): Add pa/t-hpux pa/t-hpux10, t-libgcc-pic to + tmake_file. + (hppa*64*-*-hpux11*): Add pa/t-hpux, pa/t-pa64, t-libgcc-pic to + tmake_file. + (hppa[12]*-*-hpux11*): Add pa/t-hpux, t-libgcc-pic to tmake_file. + (i[34567]86-*-elf*): Add t-libgcc-pic to tmake_file. + (x86_64-*-elf*): Likewise. + (i[34567]86-*-nto-qnx*): Likewise. + (i[34567]86-*-mingw*): Add i386/t-gthr-win32 to tmake_file for + win32 threads. + (x86_64-*-mingw*): Likewise. + (i[34567]86-*-interix3*): Add i386/t-interix to tmake_file. + (lm32-*-uclinux*): Add t-libgcc-pic to tmake_file. + (mipsisa32-*-elf*, mipsisa32el-*-elf*, mipsisa32r2-*-elf*) + (mipsisa32r2el-*-elf*, mipsisa64-*-elf*, mipsisa64el-*-elf*) + (mipsisa64r2-*-elf*, mipsisa64r2el-*-elf*): Add mips/t-elf to + tmake_file. + (mipsisa64sr71k-*-elf*): Likewise. + (mipsisa64sb1-*-elf*, mipsisa64sb1el-*-elf*): Likewise. + (mips-*-elf*, mipsel-*-elf*): Likewise. + (mips64-*-elf*, mips64el-*-elf*): Likewise. + (mips64orion-*-elf*, mips64orionel-*-elf*): Likewise. + (mips*-*-rtems*): Likewise. + (mips64vr-*-elf*, mips64vrel-*-elf*): Add mips/t-elf, mips/t-vr + to tmake_file. + (pdp11-*-*): Add pdp11/t-pdp11 to tmake_file. + (powerpc64-*-darwin*): Add rs6000/t-darwin64 to tmake_file. + (s390x-ibm-tpf*): Add t-libgcc-pic to tmake_file. + (spu-*-elf*): Likewise. + (tic6x-*-uclinux): Add t-libgcc-pic to tmake_file. + +2011-11-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + * Makefile.in ($(lib1asmfuncs-o), $(lib1asmfuncs-s-o)): Use $(srcdir) to refer to $(LIB1ASMSRC). Use $<. diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index 6bbb369..c0d496e 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -22,7 +22,6 @@ libgcc_topdir = @libgcc_topdir@ host_subdir = @host_subdir@ -gcc_srcdir = $(libgcc_topdir)/gcc gcc_objdir = $(MULTIBUILDTOP)../../$(host_subdir)/gcc srcdir = @srcdir@ @@ -220,6 +219,42 @@ else DECNUMINC = endif +# Options to use when compiling libgcc2.a. +# +LIBGCC2_DEBUG_CFLAGS = -g +LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \ + $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) \ + -DIN_LIBGCC2 \ + -fbuilding-libgcc -fno-stack-protector \ + $(INHIBIT_LIBC_CFLAGS) + +# Additional options to use when compiling libgcc2.a. +# Some targets override this to -isystem include +LIBGCC2_INCLUDES = + +# Additional target-dependent options for compiling libgcc2.a. +HOST_LIBGCC2_CFLAGS = + +PICFLAG = @PICFLAG@ + +# Defined in libgcc2.c, included only in the static library. +LIB2FUNCS_ST = _eprintf __gcc_bcmp + +# List of functions not to build from libgcc2.c. +LIB2FUNCS_EXCLUDE = + +# These might cause a divide overflow trap and so are compiled with +# unwinder info. +LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udiv_w_sdiv _udivmoddi4 + +# List of extra C and assembler files to add to static and shared libgcc2. +# Assembler files should have names ending in `.S'. +LIB2ADD = + +# List of extra C and assembler files to add to static libgcc2. +# Assembler files should have names ending in `.S'. +LIB2ADD_ST = + # Specify the directories to be searched for header files. # Both . and srcdir are used, in that order, # so that *config.h will be found in the compilation @@ -416,15 +451,14 @@ endif # Build lib2funcs. For the static library also include LIB2FUNCS_ST. lib2funcs-o = $(patsubst %,%$(objext),$(lib2funcs) $(LIB2FUNCS_ST)) -$(lib2funcs-o): %$(objext): $(gcc_srcdir)/libgcc2.c - $(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \ - $(vis_hide) +$(lib2funcs-o): %$(objext): $(srcdir)/libgcc2.c + $(gcc_compile) -DL$* -c $< $(vis_hide) libgcc-objects += $(lib2funcs-o) ifeq ($(enable_shared),yes) lib2funcs-s-o = $(patsubst %,%_s$(objext),$(lib2funcs)) -$(lib2funcs-s-o): %_s$(objext): $(gcc_srcdir)/libgcc2.c - $(gcc_s_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c +$(lib2funcs-s-o): %_s$(objext): $(srcdir)/libgcc2.c + $(gcc_s_compile) -DL$* -c $< libgcc-s-objects += $(lib2funcs-s-o) endif @@ -452,15 +486,15 @@ endif # Build LIB2_DIVMOD_FUNCS. lib2-divmod-o = $(patsubst %,%$(objext),$(LIB2_DIVMOD_FUNCS)) -$(lib2-divmod-o): %$(objext): $(gcc_srcdir)/libgcc2.c - $(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \ +$(lib2-divmod-o): %$(objext): $(srcdir)/libgcc2.c + $(gcc_compile) -DL$* -c $< \ -fexceptions -fnon-call-exceptions $(vis_hide) libgcc-objects += $(lib2-divmod-o) ifeq ($(enable_shared),yes) lib2-divmod-s-o = $(patsubst %,%_s$(objext),$(LIB2_DIVMOD_FUNCS)) -$(lib2-divmod-s-o): %_s$(objext): $(gcc_srcdir)/libgcc2.c - $(gcc_s_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \ +$(lib2-divmod-s-o): %_s$(objext): $(srcdir)/libgcc2.c + $(gcc_s_compile) -DL$* -c $< \ -fexceptions -fnon-call-exceptions libgcc-s-objects += $(lib2-divmod-s-o) endif @@ -1027,11 +1061,3 @@ install-strip: install .NOEXPORT: include $(srcdir)/empty.mk $(wildcard *.dep) - -# TODO QUEUE: -# Garbage collect in gcc/: -# $(LIBGCC) settings in t-* are now unused -# -# Remove use of $(gcc_srcdir). Source files referenced using $(gcc_srcdir) -# should move into the libgcc directory. - diff --git a/libgcc/config.host b/libgcc/config.host index 0a05ea1..c4f445f 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -163,7 +163,7 @@ esac case ${host} in *-*-darwin*) asm_hidden_op=.private_extern - tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-slibgcc-darwin" + 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*) @@ -179,10 +179,11 @@ case ${host} in # This is the generic ELF configuration of FreeBSD. Later # machine-specific sections may refine and add to this # configuration. - tmake_file="$tmake_file t-crtstuff-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver" + tmake_file="$tmake_file t-freebsd t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver" extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o" case ${target_thread_file} in posix) + tmake_file="${tmake_file} t-freebsd-thread" # Before 5.0, FreeBSD can't bind shared libraries to -lc # when "optionally" threaded via weak pthread_* checks. case ${host} in @@ -194,15 +195,15 @@ case ${host} in esac ;; *-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu) - tmake_file="$tmake_file t-crtstuff-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-linux" + tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-linux" extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o" ;; *-*-lynxos*) - tmake_file="$tmake_file $cpu_type/t-crtstuff t-crtstuff-pic" + tmake_file="$tmake_file t-lynx $cpu_type/t-crtstuff t-crtstuff-pic t-libgcc-pic" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" ;; *-*-netbsd*) - tmake_file="$tmake_file t-crtstuff-pic t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver" + tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver" # NetBSD 1.7 and later are set up to use GCC's crtstuff for # ELF configurations. We will clear extra_parts in the # a.out configurations. @@ -213,7 +214,12 @@ case ${host} in esac ;; *-*-openbsd*) - tmake_file="$tmake_file t-crtstuff-pic" + tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic" + case ${target_thread_file} in + posix) + tmake_file="$tmake_file t-openbsd-thread" + ;; + esac ;; *-*-rtems*) extra_parts="crtbegin.o crtend.o" @@ -221,7 +227,7 @@ case ${host} in *-*-solaris2*) # Unless linker support and dl_iterate_phdr are present, # unwind-dw2-fde-dip.c automatically falls back to unwind-dw2-fde.c. - tmake_file="$tmake_file t-sol2 t-eh-dw2-dip t-slibgcc t-slibgcc-elf-ver" + tmake_file="$tmake_file t-sol2 t-eh-dw2-dip t-libgcc-pic t-slibgcc t-slibgcc-elf-ver" if test $with_gnu_ld = yes; then tmake_file="$tmake_file t-slibgcc-gld" else @@ -252,6 +258,7 @@ case ${host} in extra_parts="vcrt0.o pcrt0.o crtbegin.o crtbeginS.o crtend.o crtendS.o" ;; *-*-vxworks*) + tmake_file=t-vxworks ;; *-*-elf) extra_parts="crtbegin.o crtend.o" @@ -273,17 +280,19 @@ esac case ${host} in alpha*-*-linux*) - tmake_file="${tmake_file} t-crtfm alpha/t-linux" + tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee t-crtfm alpha/t-linux" extra_parts="$extra_parts crtfastmath.o" md_unwind_header=alpha/linux-unwind.h ;; alpha*-*-freebsd*) - tmake_file="${tmake_file} t-crtfm" + tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee t-crtfm" extra_parts="$extra_parts crtbeginT.o crtfastmath.o" ;; alpha*-*-netbsd*) + tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee" ;; alpha*-*-openbsd*) + tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee" ;; alpha*-dec-osf5.1*) tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee t-crtfm t-slibgcc alpha/t-slibgcc-osf" @@ -292,16 +301,16 @@ alpha*-dec-osf5.1*) tmake_file="${tmake_file} alpha/t-osf-pthread" ;; esac - extra_parts="${extra_parts} qrnnd.o crtfastmath.o gthr-posix.o" + extra_parts="${extra_parts} crtfastmath.o" md_unwind_header=alpha/osf5-unwind.h ;; alpha64-dec-*vms*) - tmake_file="$tmake_file alpha/t-vms t-slibgcc-vms" + tmake_file="$tmake_file alpha/t-alpha alpha/t-ieee alpha/t-vms t-slibgcc-vms" extra_parts="$extra_parts vms-dwarf2.o vms-dwarf2eh.o" md_unwind_header=alpha/vms-unwind.h ;; alpha*-dec-*vms*) - tmake_file="$tmake_file alpha/t-vms t-slibgcc-vms" + tmake_file="$tmake_file alpha/t-alpha alpha/t-ieee alpha/t-vms t-slibgcc-vms" extra_parts="$extra_parts vms-dwarf2.o vms-dwarf2eh.o" md_unwind_header=alpha/vms-unwind.h ;; @@ -313,7 +322,7 @@ arm*-*-freebsd*) tmake_file="$tmake_file arm/t-arm arm/t-strongarm-elf t-fdpbit" ;; arm*-*-netbsdelf*) - tmake_file="$tmake_file arm/t-arm t-slibgcc-gld-nover" + tmake_file="$tmake_file arm/t-arm arm/t-netbsd t-slibgcc-gld-nover" ;; arm*-*-linux*) # ARM GNU/Linux with ELF tmake_file="${tmake_file} arm/t-arm t-fixedpoint-gnu-prefix" @@ -379,16 +388,16 @@ avr-*-*) tmake_file="${cpu_type}/t-avr t-fpbit" ;; bfin*-elf*) - tmake_file="bfin/t-bfin bfin/t-crtlibid bfin/t-crtstuff t-fdpbit" + tmake_file="bfin/t-bfin bfin/t-elf bfin/t-crtlibid bfin/t-crtstuff t-fdpbit" extra_parts="$extra_parts crtbeginS.o crtendS.o crti.o crtn.o crtlibid.o" ;; bfin*-uclinux*) - tmake_file="bfin/t-bfin bfin/t-crtlibid bfin/t-crtstuff t-fdpbit" + tmake_file="bfin/t-bfin bfin/t-elf bfin/t-crtlibid bfin/t-crtstuff t-fdpbit" extra_parts="$extra_parts crtbeginS.o crtendS.o crtlibid.o" md_unwind_header=bfin/linux-unwind.h ;; bfin*-linux-uclibc*) - tmake_file="$tmake_file bfin/t-bfin bfin/t-crtstuff t-fdpbit bfin/t-linux" + tmake_file="$tmake_file bfin/t-bfin bfin/t-elf bfin/t-crtstuff t-fdpbit bfin/t-linux" # No need to build crtbeginT.o on uClibc systems. Should probably # be moved to the OS specific section above. extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" @@ -403,21 +412,21 @@ bfin*-*) extra_parts="crtbegin.o crtend.o crti.o crtn.o" ;; crisv32-*-elf) - tmake_file=t-fdpbit + tmake_file="cris/t-cris t-fdpbit" ;; crisv32-*-none) - tmake_file=t-fdpbit + tmake_file="cris/t-cris t-fdpbit" extra_parts="crtbegin.o crtend.o" ;; cris-*-elf) - tmake_file="$tmake_file cris/t-elfmulti" + tmake_file="$tmake_file cris/t-cris cris/t-elfmulti" ;; cris-*-none) - tmake_file="$tmake_file cris/t-elfmulti" + tmake_file="$tmake_file cris/t-cris cris/t-elfmulti" extra_parts="crtbegin.o crtend.o" ;; cris-*-linux* | crisv32-*-linux*) - tmake_file="$tmake_file t-fdpbit cris/t-linux" + tmake_file="$tmake_file cris/t-cris t-fdpbit cris/t-linux" ;; fr30-*-elf) tmake_file="$tmake_file fr30/t-fr30 t-fdpbit" @@ -453,7 +462,7 @@ hppa*-*-linux*) md_unwind_header=pa/linux-unwind.h ;; hppa[12]*-*-hpux10*) - tmake_file="$tmake_file t-slibgcc" + tmake_file="$tmake_file pa/t-hpux pa/t-hpux10 t-libgcc-pic t-slibgcc" # Set the libgcc version number if test x$enable_sjlj_exceptions = xyes; then tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver" @@ -464,7 +473,7 @@ hppa[12]*-*-hpux10*) md_unwind_header=pa/hpux-unwind.h ;; hppa*64*-*-hpux11*) - tmake_file="$tmake_file pa/t-stublib pa/t-stublib64 t-slibgcc" + tmake_file="$tmake_file pa/t-hpux pa/t-pa64 pa/t-stublib pa/t-stublib64 t-libgcc-pic t-slibgcc" # Set the libgcc version number if test x$enable_sjlj_exceptions = xyes; then tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver" @@ -477,7 +486,7 @@ hppa*64*-*-hpux11*) md_unwind_header=pa/hpux-unwind.h ;; hppa[12]*-*-hpux11*) - tmake_file="$tmake_file pa/t-stublib t-slibgcc" + tmake_file="$tmake_file pa/t-hpux pa/t-stublib t-libgcc-pic t-slibgcc" # Set the libgcc version number if test x$enable_sjlj_exceptions = xyes; then tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver" @@ -497,10 +506,10 @@ x86_64-*-darwin*) extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" ;; i[34567]86-*-elf*) - tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic" + tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" ;; x86_64-*-elf*) - tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic" + tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" ;; i[34567]86-*-freebsd*) tmake_file="${tmake_file} i386/t-freebsd i386/t-crtstuff" @@ -540,7 +549,7 @@ i[34567]86-pc-msdosdjgpp*) i[34567]86-*-lynxos*) ;; i[34567]86-*-nto-qnx*) - tmake_file="$tmake_file i386/t-nto" + tmake_file="$tmake_file i386/t-nto t-libgcc-pic" extra_parts=crtbegin.o ;; i[34567]86-*-rtems*) @@ -577,6 +586,11 @@ i[34567]86-*-cygwin*) ;; i[34567]86-*-mingw*) extra_parts="crtbegin.o crtend.o crtfastmath.o" + case ${target_thread_file} in + win32) + tmake_file="$tmake_file i386/t-gthr-win32" + ;; + esac # This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h if test x$enable_sjlj_exceptions = xyes; then tmake_eh_file="i386/t-sjlj-eh" @@ -593,6 +607,11 @@ i[34567]86-*-mingw*) md_unwind_header=i386/w32-unwind.h ;; x86_64-*-mingw*) + case ${target_thread_file} in + win32) + tmake_file="$tmake_file i386/t-gthr-win32" + ;; + esac # This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h if test x$enable_sjlj_exceptions = xyes; then tmake_eh_file="i386/t-sjlj-eh" @@ -609,7 +628,7 @@ x86_64-*-mingw*) extra_parts="$extra_parts crtfastmath.o" ;; i[34567]86-*-interix3*) - tmake_file="$tmake_file i386/t-chkstk" + tmake_file="$tmake_file i386/t-interix i386/t-chkstk" ;; ia64*-*-elf*) extra_parts="$extra_parts crtbeginS.o crtendS.o crtfastmath.o" @@ -647,7 +666,7 @@ lm32-*-elf*|lm32-*-rtems*) ;; lm32-*-uclinux*) extra_parts="$extra_parts crtbegin.o crtendS.o crtbeginT.o" - tmake_file="lm32/t-lm32 lm32/t-uclinux t-softfp-sfdf t-softfp" + tmake_file="lm32/t-lm32 lm32/t-uclinux t-libgcc-pic t-softfp-sfdf t-softfp" ;; m32r-*-elf*) tmake_file=t-fdpbit @@ -737,35 +756,35 @@ mipsisa32-*-elf* | mipsisa32el-*-elf* | \ mipsisa32r2-*-elf* | mipsisa32r2el-*-elf* | \ mipsisa64-*-elf* | mipsisa64el-*-elf* | \ mipsisa64r2-*-elf* | mipsisa64r2el-*-elf*) - tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16" + tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16" extra_parts="$extra_parts crti.o crtn.o" ;; mipsisa64sr71k-*-elf*) - tmake_file="mips/t-crtstuff t-fdpbit" + tmake_file="mips/t-elf mips/t-crtstuff t-fdpbit" extra_parts="$extra_parts crti.o crtn.o" ;; mipsisa64sb1-*-elf* | mipsisa64sb1el-*-elf*) - tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16" + tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16" extra_parts="$extra_parts crti.o crtn.o" ;; mips-*-elf* | mipsel-*-elf*) - tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16" + tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16" extra_parts="$extra_parts crti.o crtn.o" ;; mips64-*-elf* | mips64el-*-elf*) - tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16" + tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16" extra_parts="$extra_parts crti.o crtn.o" ;; mips64vr-*-elf* | mips64vrel-*-elf*) - tmake_file="$tmake_file mips/t-crtstuff" + tmake_file="$tmake_file mips/t-elf mips/t-vr mips/t-crtstuff" extra_parts="$extra_parts crti.o crtn.o" ;; mips64orion-*-elf* | mips64orionel-*-elf*) - tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16" + tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16" extra_parts="$extra_parts crti.o crtn.o" ;; mips*-*-rtems*) - tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16" + tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16" extra_parts="$extra_parts crti.o crtn.o" ;; mips-wrs-vxworks) @@ -790,7 +809,7 @@ moxie-*-rtems*) extra_parts= ;; pdp11-*-*) - tmake_file=t-fdpbit + tmake_file="pdp11/t-pdp11 t-fdpbit" ;; picochip-*-*) tmake_file="picochip/t-picochip t-fpbit" @@ -809,7 +828,7 @@ powerpc-*-darwin*) extra_parts="$extra_parts crt2.o" ;; powerpc64-*-darwin*) - tmake_file="$tmake_file rs6000/t-ibm-ldouble" + tmake_file="$tmake_file rs6000/t-darwin64 rs6000/t-ibm-ldouble" extra_parts="$extra_parts crt2.o" ;; powerpc-*-freebsd*) @@ -898,7 +917,7 @@ s390x-*-linux*) md_unwind_header=s390/linux-unwind.h ;; s390x-ibm-tpf*) - tmake_file="${tmake_file} s390/t-crtstuff s390/t-tpf t-eh-dw2-dip" + tmake_file="${tmake_file} s390/t-crtstuff t-libgcc-pic t-eh-dw2-dip" extra_parts="crtbeginS.o crtendS.o" md_unwind_header=s390/tpf-unwind.h ;; @@ -1019,14 +1038,14 @@ sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux sparc64-*-netbsd*) ;; spu-*-elf*) - tmake_file="$tmake_file spu/t-elf t-fdpbit" + tmake_file="$tmake_file spu/t-elf t-libgcc-pic t-fdpbit" extra_parts="$extra_parts \ libgcc_cachemgr.a libgcc_cachemgr_nonatomic.a \ libgcc_cache8k.a libgcc_cache16k.a libgcc_cache32k.a \ libgcc_cache64k.a libgcc_cache128k.a" ;; tic6x-*-uclinux) - tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp c6x/t-elf c6x/t-uclinux t-crtstuff-pic t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-gnu-prefix" + tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp c6x/t-elf c6x/t-uclinux t-crtstuff-pic t-libgcc-pic t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-gnu-prefix" extra_parts="crtbeginS.o crtendS.o crti.o crtn.o" unwind_header=config/c6x/unwind-c6x.h ;; diff --git a/libgcc/config/alpha/gthr-posix.c b/libgcc/config/alpha/gthr-posix.c new file mode 100644 index 0000000..4242cd6 --- /dev/null +++ b/libgcc/config/alpha/gthr-posix.c @@ -0,0 +1,265 @@ +/* POSIX threads dummy routines for systems without weak definitions. */ +/* Compile this one with gcc. */ +/* Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "tconfig.h" +#include "tm.h" +# define __gthrw_pragma(pragma) _Pragma (#pragma) +/* Define so we provide weak definitions of functions used by libobjc only. */ +#define _LIBOBJC_WEAK +#include "gthr.h" + +int +pthread_once (pthread_once_t *once ATTRIBUTE_UNUSED, + void (*func) (void) ATTRIBUTE_UNUSED) +{ + return -1; +} + +int +pthread_key_create (pthread_key_t *key ATTRIBUTE_UNUSED, + void (*dtor) (void *) ATTRIBUTE_UNUSED) +{ + return -1; +} + +int +pthread_key_delete (pthread_key_t key ATTRIBUTE_UNUSED) +{ + return 0; +} + +void * +pthread_getspecific (pthread_key_t key ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_setspecific (pthread_key_t key ATTRIBUTE_UNUSED, + const void *ptr ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_create (pthread_t *thread ATTRIBUTE_UNUSED, + const pthread_attr_t *attr ATTRIBUTE_UNUSED, + void *(*start_routine) (void *) ATTRIBUTE_UNUSED, + void *arg ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_join (pthread_t thread ATTRIBUTE_UNUSED, + void **value_ptr ATTRIBUTE_UNUSED) +{ + return 0; +} + +void +pthread_exit (void *value_ptr ATTRIBUTE_UNUSED) +{ +} + +int +pthread_detach (pthread_t thread ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_cancel (pthread_t thread ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_mutex_lock (pthread_mutex_t *mutex ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_mutex_trylock (pthread_mutex_t *mutex ATTRIBUTE_UNUSED) +{ + return 0; +} + +#ifdef _POSIX_TIMEOUTS +#if _POSIX_TIMEOUTS >= 0 +int +pthread_mutex_timedlock (pthread_mutex_t *mutex ATTRIBUTE_UNUSED, + const struct timespec *abs_timeout ATTRIBUTE_UNUSED) +{ + return 0; +} +#endif +#endif /* _POSIX_TIMEOUTS */ + +int +pthread_mutex_unlock (pthread_mutex_t *mutex ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_mutexattr_init (pthread_mutexattr_t *attr ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_mutexattr_settype (pthread_mutexattr_t *attr ATTRIBUTE_UNUSED, + int type ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_mutexattr_destroy (pthread_mutexattr_t *attr ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_cond_broadcast (pthread_cond_t *cond ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_cond_destroy (pthread_cond_t *cond ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_cond_init (pthread_cond_t *cond ATTRIBUTE_UNUSED, + const pthread_condattr_t *attr ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_cond_signal (pthread_cond_t *cond ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_cond_wait (pthread_cond_t *cond ATTRIBUTE_UNUSED, + pthread_mutex_t *mutex ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_cond_timedwait (pthread_cond_t *cond ATTRIBUTE_UNUSED, + pthread_mutex_t *mutex ATTRIBUTE_UNUSED, + const struct timespec *abstime ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_mutex_init (pthread_mutex_t *mutex ATTRIBUTE_UNUSED, + const pthread_mutexattr_t *attr ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_mutex_destroy (pthread_mutex_t *mutex ATTRIBUTE_UNUSED) +{ + return 0; +} + +pthread_t +pthread_self (void) +{ + return (pthread_t) 0; +} + +#ifdef _POSIX_PRIORITY_SCHEDULING +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +int +sched_get_priority_max (int policy ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +sched_get_priority_min (int policy ATTRIBUTE_UNUSED) +{ + return 0; +} +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +#endif /* _POSIX_PRIORITY_SCHEDULING */ + +int +sched_yield (void) +{ + return 0; +} + +int +pthread_attr_destroy (pthread_attr_t *attr ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_attr_init (pthread_attr_t *attr ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_attr_setdetachstate (pthread_attr_t *attr ATTRIBUTE_UNUSED, + int detachstate ATTRIBUTE_UNUSED) +{ + return 0; +} + +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +int +pthread_getschedparam (pthread_t thread ATTRIBUTE_UNUSED, + int *policy ATTRIBUTE_UNUSED, + struct sched_param *param ATTRIBUTE_UNUSED) +{ + return 0; +} + +int +pthread_setschedparam (pthread_t thread ATTRIBUTE_UNUSED, + int policy ATTRIBUTE_UNUSED, + const struct sched_param *param ATTRIBUTE_UNUSED) +{ + return 0; +} +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + diff --git a/libgcc/config/alpha/qrnnd.S b/libgcc/config/alpha/qrnnd.S new file mode 100644 index 0000000..51b13bc --- /dev/null +++ b/libgcc/config/alpha/qrnnd.S @@ -0,0 +1,163 @@ + # Alpha 21064 __udiv_qrnnd + # Copyright (C) 1992, 1994, 1995, 2000, 2009 Free Software Foundation, Inc. + + # This file is part of GCC. + + # The GNU MP Library 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 of the License, or (at your + # option) any later version. + + # This file 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 Library 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/>. + +#ifdef __ELF__ +.section .note.GNU-stack,"" +#endif + + .set noreorder + .set noat + + .text + + .globl __udiv_qrnnd + .ent __udiv_qrnnd +__udiv_qrnnd: + .frame $30,0,$26,0 + .prologue 0 + +#define cnt $2 +#define tmp $3 +#define rem_ptr $16 +#define n1 $17 +#define n0 $18 +#define d $19 +#define qb $20 +#define AT $at + + ldiq cnt,16 + blt d,$largedivisor + +$loop1: cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + subq cnt,1,cnt + bgt cnt,$loop1 + stq n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + +$largedivisor: + and n0,1,$4 + + srl n0,1,n0 + sll n1,63,tmp + or tmp,n0,n0 + srl n1,1,n1 + + and d,1,$6 + srl d,1,$5 + addq $5,$6,$5 + +$loop2: cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + subq cnt,1,cnt + bgt cnt,$loop2 + + addq n1,n1,n1 + addq $4,n1,n1 + bne $6,$Odd + stq n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + +$Odd: + /* q' in n0. r' in n1 */ + addq n1,n0,n1 + + cmpult n1,n0,tmp # tmp := carry from addq + subq n1,d,AT + addq n0,tmp,n0 + cmovne tmp,AT,n1 + + cmpult n1,d,tmp + addq n0,1,AT + cmoveq tmp,AT,n0 + subq n1,d,AT + cmoveq tmp,AT,n1 + + stq n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + + .end __udiv_qrnnd diff --git a/libgcc/config/alpha/t-alpha b/libgcc/config/alpha/t-alpha index 14c72d0..0b6ffb1 100644 --- a/libgcc/config/alpha/t-alpha +++ b/libgcc/config/alpha/t-alpha @@ -1,2 +1,2 @@ # This is a support routine for longlong.h, used by libgcc2.c. -LIB2ADD += $(gcc_srcdir)/config/alpha/qrnnd.asm +LIB2ADD += $(srcdir)/config/alpha/qrnnd.S diff --git a/libgcc/config/alpha/t-osf-pthread b/libgcc/config/alpha/t-osf-pthread index c51f375..9a175db 100644 --- a/libgcc/config/alpha/t-osf-pthread +++ b/libgcc/config/alpha/t-osf-pthread @@ -2,4 +2,4 @@ HOST_LIBGCC2_CFLAGS += -pthread # Provide dummy POSIX threads functions -LIB2ADD += $(gcc_srcdir)/gthr-posix.c +LIB2ADD += $(srcdir)/config/alpha/gthr-posix.c diff --git a/libgcc/config/alpha/t-vms b/libgcc/config/alpha/t-vms index 21d6d71..dd5760d 100644 --- a/libgcc/config/alpha/t-vms +++ b/libgcc/config/alpha/t-vms @@ -5,3 +5,5 @@ vms-dwarf2.o: $(srcdir)/config/alpha/vms-dwarf2.S vms-dwarf2eh.o: $(srcdir)/config/alpha/vms-dwarf2eh.S $(gcc_compile) -c -x assembler-with-cpp $< + +LIB2ADD += $(srcdir)/config/alpha/vms-gcc_shell_handler.c diff --git a/libgcc/config/alpha/vms-gcc_shell_handler.c b/libgcc/config/alpha/vms-gcc_shell_handler.c new file mode 100644 index 0000000..67d0fe7 --- /dev/null +++ b/libgcc/config/alpha/vms-gcc_shell_handler.c @@ -0,0 +1,124 @@ +/* Static condition handler for Alpha/VMS. + Copyright (C) 2005-2009 + Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* This file implements __gcc_shell_handler, the static VMS condition handler + used as the indirection wrapper around user level handlers installed with + establish_vms_condition_handler GCC builtin. + + [ABI] in comments refers to the "HP OpenVMS calling standard" document + dated January 2005. */ + +#include <vms/chfdef.h> +#include <vms/pdscdef.h> +#include <vms/ssdef.h> + +typedef void * ADDR; +typedef unsigned long long REG; + +#define REG_AT(addr) (*(REG *)(addr)) + +/* Compute pointer to procedure descriptor (Procedure Value) from Frame + Pointer FP, according to the rules in [ABI-3.5.1 Current Procedure]. */ +#define PV_FOR(FP) \ + (((FP) != 0) \ + ? (((REG_AT (FP) & 0x7) == 0) ? *(PDSCDEF **)(FP) : (PDSCDEF *)(FP)) : 0) + +long +__gcc_shell_handler (struct chf$signal_array *sig_arr, + struct chf$mech_array *mech_arr); + +/* Helper for __gcc_shell_handler. Fetch the pointer to procedure currently + registered as the VMS condition handler for the live function with a frame + pointer FP. */ + +static ADDR +get_dyn_handler_pointer (REG fp) +{ + /* From the frame pointer we find the procedure descriptor, and fetch + the handler_data field from there. This field contains the offset + from FP at which the address of the currently installed handler is + to be found. */ + + PDSCDEF * pd = PV_FOR (fp); + /* Procedure descriptor pointer for the live subprogram with FP as the frame + pointer, and to which _gcc_shell_handler is attached as a condition + handler. */ + + REG handler_slot_offset; + /* Offset from FP at which the address of the currently established real + condition handler is to be found. This offset is available from the + handler_data field of the procedure descriptor. */ + + REG handler_data_offset; + /* The handler_data field position in the procedure descriptor, which + depends on the kind of procedure at hand. */ + + switch (pd->pdsc$w_flags & 0xf) + { + case PDSC$K_KIND_FP_STACK: /* [3.4.2 PD for stack frame procedures] */ + handler_data_offset = 40; + break; + + case PDSC$K_KIND_FP_REGISTER: /* [3.4.5 PD for reg frame procedures] */ + handler_data_offset = 32; + break; + + default: + handler_data_offset = 0; + break; + } + + /* If we couldn't determine the handler_data field position, give up. */ + if (handler_data_offset == 0) + return 0; + + /* Otherwise, fetch the fp offset at which the real handler address is to be + found, then fetch and return the latter in turn. */ + + handler_slot_offset = REG_AT ((REG)pd + handler_data_offset); + + return (ADDR) REG_AT (fp + handler_slot_offset); +} + +/* The static VMS condition handler for GCC code. Fetch the address of the + currently established condition handler, then resignal if there is none or + call the handler with the VMS condition arguments. */ + +long +__gcc_shell_handler (struct chf$signal_array *sig_arr, + struct chf$mech_array *mech_arr) +{ + long ret; + long (*user_handler) (struct chf$signal_array *, struct chf$mech_array *); + + user_handler = get_dyn_handler_pointer (mech_arr->chf$q_mch_frame); + if (!user_handler) + ret = SS$_RESIGNAL; + else + ret = user_handler (sig_arr, mech_arr); + + return ret; +} + diff --git a/libgcc/config/arm/bpabi.c b/libgcc/config/arm/bpabi.c new file mode 100644 index 0000000..283bdc0 --- /dev/null +++ b/libgcc/config/arm/bpabi.c @@ -0,0 +1,56 @@ +/* Miscellaneous BPABI functions. + + Copyright (C) 2003, 2004, 2009 Free Software Foundation, Inc. + Contributed by CodeSourcery, LLC. + + This file 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. + + This file 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/>. */ + +extern long long __divdi3 (long long, long long); +extern unsigned long long __udivdi3 (unsigned long long, + unsigned long long); +extern long long __gnu_ldivmod_helper (long long, long long, long long *); +extern unsigned long long __gnu_uldivmod_helper (unsigned long long, + unsigned long long, + unsigned long long *); + + +long long +__gnu_ldivmod_helper (long long a, + long long b, + long long *remainder) +{ + long long quotient; + + quotient = __divdi3 (a, b); + *remainder = a - b * quotient; + return quotient; +} + +unsigned long long +__gnu_uldivmod_helper (unsigned long long a, + unsigned long long b, + unsigned long long *remainder) +{ + unsigned long long quotient; + + quotient = __udivdi3 (a, b); + *remainder = a - b * quotient; + return quotient; +} diff --git a/libgcc/config/arm/fp16.c b/libgcc/config/arm/fp16.c new file mode 100644 index 0000000..936caeb --- /dev/null +++ b/libgcc/config/arm/fp16.c @@ -0,0 +1,145 @@ +/* Half-float conversion routines. + + Copyright (C) 2008, 2009 Free Software Foundation, Inc. + Contributed by CodeSourcery. + + This file 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. + + This file 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/>. */ + +static inline unsigned short +__gnu_f2h_internal(unsigned int a, int ieee) +{ + unsigned short sign = (a >> 16) & 0x8000; + int aexp = (a >> 23) & 0xff; + unsigned int mantissa = a & 0x007fffff; + unsigned int mask; + unsigned int increment; + + if (aexp == 0xff) + { + if (!ieee) + return sign; + return sign | 0x7e00 | (mantissa >> 13); + } + + if (aexp == 0 && mantissa == 0) + return sign; + + aexp -= 127; + + /* Decimal point between bits 22 and 23. */ + mantissa |= 0x00800000; + if (aexp < -14) + { + mask = 0x007fffff; + if (aexp < -25) + aexp = -26; + else if (aexp != -25) + mask >>= 24 + aexp; + } + else + mask = 0x00001fff; + + /* Round. */ + if (mantissa & mask) + { + increment = (mask + 1) >> 1; + if ((mantissa & mask) == increment) + increment = mantissa & (increment << 1); + mantissa += increment; + if (mantissa >= 0x01000000) + { + mantissa >>= 1; + aexp++; + } + } + + if (ieee) + { + if (aexp > 15) + return sign | 0x7c00; + } + else + { + if (aexp > 16) + return sign | 0x7fff; + } + + if (aexp < -24) + return sign; + + if (aexp < -14) + { + mantissa >>= -14 - aexp; + aexp = -14; + } + + /* We leave the leading 1 in the mantissa, and subtract one + from the exponent bias to compensate. */ + return sign | (((aexp + 14) << 10) + (mantissa >> 13)); +} + +unsigned int +__gnu_h2f_internal(unsigned short a, int ieee) +{ + unsigned int sign = (unsigned int)(a & 0x8000) << 16; + int aexp = (a >> 10) & 0x1f; + unsigned int mantissa = a & 0x3ff; + + if (aexp == 0x1f && ieee) + return sign | 0x7f800000 | (mantissa << 13); + + if (aexp == 0) + { + int shift; + + if (mantissa == 0) + return sign; + + shift = __builtin_clz(mantissa) - 21; + mantissa <<= shift; + aexp = -shift; + } + + return sign | (((aexp + 0x70) << 23) + (mantissa << 13)); +} + +unsigned short +__gnu_f2h_ieee(unsigned int a) +{ + return __gnu_f2h_internal(a, 1); +} + +unsigned int +__gnu_h2f_ieee(unsigned short a) +{ + return __gnu_h2f_internal(a, 1); +} + +unsigned short +__gnu_f2h_alternative(unsigned int x) +{ + return __gnu_f2h_internal(x, 0); +} + +unsigned int +__gnu_h2f_alternative(unsigned short a) +{ + return __gnu_h2f_internal(a, 0); +} diff --git a/libgcc/config/arm/linux-atomic-64bit.c b/libgcc/config/arm/linux-atomic-64bit.c new file mode 100644 index 0000000..af94c7f --- /dev/null +++ b/libgcc/config/arm/linux-atomic-64bit.c @@ -0,0 +1,166 @@ +/* 64bit Linux-specific atomic operations for ARM EABI. + Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Based on linux-atomic.c + + 64 bit additions david.gilbert@linaro.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/>. */ + +/* 64bit helper functions for atomic operations; the compiler will + call these when the code is compiled for a CPU without ldrexd/strexd. + (If the CPU had those then the compiler inlines the operation). + + These helpers require a kernel helper that's only present on newer + kernels; we check for that in an init section and bail out rather + unceremoneously. */ + +extern unsigned int __write (int fd, const void *buf, unsigned int count); +extern void abort (void); + +/* Kernel helper for compare-and-exchange. */ +typedef int (__kernel_cmpxchg64_t) (const long long* oldval, + const long long* newval, + long long *ptr); +#define __kernel_cmpxchg64 (*(__kernel_cmpxchg64_t *) 0xffff0f60) + +/* Kernel helper page version number. */ +#define __kernel_helper_version (*(unsigned int *)0xffff0ffc) + +/* Check that the kernel has a new enough version at load. */ +static void __check_for_sync8_kernelhelper (void) +{ + if (__kernel_helper_version < 5) + { + const char err[] = "A newer kernel is required to run this binary. " + "(__kernel_cmpxchg64 helper)\n"; + /* At this point we need a way to crash with some information + for the user - I'm not sure I can rely on much else being + available at this point, so do the same as generic-morestack.c + write () and abort (). */ + __write (2 /* stderr. */, err, sizeof (err)); + abort (); + } +}; + +static void (*__sync8_kernelhelper_inithook[]) (void) + __attribute__ ((used, section (".init_array"))) = { + &__check_for_sync8_kernelhelper +}; + +#define HIDDEN __attribute__ ((visibility ("hidden"))) + +#define FETCH_AND_OP_WORD64(OP, PFX_OP, INF_OP) \ + long long HIDDEN \ + __sync_fetch_and_##OP##_8 (long long *ptr, long long val) \ + { \ + int failure; \ + long long tmp,tmp2; \ + \ + do { \ + tmp = *ptr; \ + tmp2 = PFX_OP (tmp INF_OP val); \ + failure = __kernel_cmpxchg64 (&tmp, &tmp2, ptr); \ + } while (failure != 0); \ + \ + return tmp; \ + } + +FETCH_AND_OP_WORD64 (add, , +) +FETCH_AND_OP_WORD64 (sub, , -) +FETCH_AND_OP_WORD64 (or, , |) +FETCH_AND_OP_WORD64 (and, , &) +FETCH_AND_OP_WORD64 (xor, , ^) +FETCH_AND_OP_WORD64 (nand, ~, &) + +#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH +#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH + +/* Implement both __sync_<op>_and_fetch and __sync_fetch_and_<op> for + subword-sized quantities. */ + +#define OP_AND_FETCH_WORD64(OP, PFX_OP, INF_OP) \ + long long HIDDEN \ + __sync_##OP##_and_fetch_8 (long long *ptr, long long val) \ + { \ + int failure; \ + long long tmp,tmp2; \ + \ + do { \ + tmp = *ptr; \ + tmp2 = PFX_OP (tmp INF_OP val); \ + failure = __kernel_cmpxchg64 (&tmp, &tmp2, ptr); \ + } while (failure != 0); \ + \ + return tmp2; \ + } + +OP_AND_FETCH_WORD64 (add, , +) +OP_AND_FETCH_WORD64 (sub, , -) +OP_AND_FETCH_WORD64 (or, , |) +OP_AND_FETCH_WORD64 (and, , &) +OP_AND_FETCH_WORD64 (xor, , ^) +OP_AND_FETCH_WORD64 (nand, ~, &) + +long long HIDDEN +__sync_val_compare_and_swap_8 (long long *ptr, long long oldval, + long long newval) +{ + int failure; + long long actual_oldval; + + while (1) + { + actual_oldval = *ptr; + + if (__builtin_expect (oldval != actual_oldval, 0)) + return actual_oldval; + + failure = __kernel_cmpxchg64 (&actual_oldval, &newval, ptr); + + if (__builtin_expect (!failure, 1)) + return oldval; + } +} + +typedef unsigned char bool; + +bool HIDDEN +__sync_bool_compare_and_swap_8 (long long *ptr, long long oldval, + long long newval) +{ + int failure = __kernel_cmpxchg64 (&oldval, &newval, ptr); + return (failure == 0); +} + +long long HIDDEN +__sync_lock_test_and_set_8 (long long *ptr, long long val) +{ + int failure; + long long oldval; + + do { + oldval = *ptr; + failure = __kernel_cmpxchg64 (&oldval, &val, ptr); + } while (failure != 0); + + return oldval; +} diff --git a/libgcc/config/arm/linux-atomic.c b/libgcc/config/arm/linux-atomic.c new file mode 100644 index 0000000..80f161d --- /dev/null +++ b/libgcc/config/arm/linux-atomic.c @@ -0,0 +1,279 @@ +/* Linux-specific atomic operations for ARM EABI. + Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + Contributed by CodeSourcery. + +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/>. */ + +/* Kernel helper for compare-and-exchange. */ +typedef int (__kernel_cmpxchg_t) (int oldval, int newval, int *ptr); +#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) + +/* Kernel helper for memory barrier. */ +typedef void (__kernel_dmb_t) (void); +#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0) + +/* Note: we implement byte, short and int versions of atomic operations using + the above kernel helpers; see linux-atomic-64bit.c for "long long" (64-bit) + operations. */ + +#define HIDDEN __attribute__ ((visibility ("hidden"))) + +#ifdef __ARMEL__ +#define INVERT_MASK_1 0 +#define INVERT_MASK_2 0 +#else +#define INVERT_MASK_1 24 +#define INVERT_MASK_2 16 +#endif + +#define MASK_1 0xffu +#define MASK_2 0xffffu + +#define FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP) \ + int HIDDEN \ + __sync_fetch_and_##OP##_4 (int *ptr, int val) \ + { \ + int failure, tmp; \ + \ + do { \ + tmp = *ptr; \ + failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ + } while (failure != 0); \ + \ + return tmp; \ + } + +FETCH_AND_OP_WORD (add, , +) +FETCH_AND_OP_WORD (sub, , -) +FETCH_AND_OP_WORD (or, , |) +FETCH_AND_OP_WORD (and, , &) +FETCH_AND_OP_WORD (xor, , ^) +FETCH_AND_OP_WORD (nand, ~, &) + +#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH +#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH + +/* Implement both __sync_<op>_and_fetch and __sync_fetch_and_<op> for + subword-sized quantities. */ + +#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \ + TYPE HIDDEN \ + NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val) \ + { \ + int *wordptr = (int *) ((unsigned int) ptr & ~3); \ + unsigned int mask, shift, oldval, newval; \ + int failure; \ + \ + shift = (((unsigned int) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ + mask = MASK_##WIDTH << shift; \ + \ + do { \ + oldval = *wordptr; \ + newval = ((PFX_OP (((oldval & mask) >> shift) \ + INF_OP (unsigned int) val)) << shift) & mask; \ + newval |= oldval & ~mask; \ + failure = __kernel_cmpxchg (oldval, newval, wordptr); \ + } while (failure != 0); \ + \ + return (RETURN & mask) >> shift; \ + } + +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) + +#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \ + int HIDDEN \ + __sync_##OP##_and_fetch_4 (int *ptr, int val) \ + { \ + int tmp, failure; \ + \ + do { \ + tmp = *ptr; \ + failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ + } while (failure != 0); \ + \ + return PFX_OP (tmp INF_OP val); \ + } + +OP_AND_FETCH_WORD (add, , +) +OP_AND_FETCH_WORD (sub, , -) +OP_AND_FETCH_WORD (or, , |) +OP_AND_FETCH_WORD (and, , &) +OP_AND_FETCH_WORD (xor, , ^) +OP_AND_FETCH_WORD (nand, ~, &) + +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) + +int HIDDEN +__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval) +{ + int actual_oldval, fail; + + while (1) + { + actual_oldval = *ptr; + + if (__builtin_expect (oldval != actual_oldval, 0)) + return actual_oldval; + + fail = __kernel_cmpxchg (actual_oldval, newval, ptr); + + if (__builtin_expect (!fail, 1)) + return oldval; + } +} + +#define SUBWORD_VAL_CAS(TYPE, WIDTH) \ + TYPE HIDDEN \ + __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ + TYPE newval) \ + { \ + int *wordptr = (int *)((unsigned int) ptr & ~3), fail; \ + unsigned int mask, shift, actual_oldval, actual_newval; \ + \ + shift = (((unsigned int) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ + mask = MASK_##WIDTH << shift; \ + \ + while (1) \ + { \ + actual_oldval = *wordptr; \ + \ + if (__builtin_expect (((actual_oldval & mask) >> shift) != \ + (unsigned int) oldval, 0)) \ + return (actual_oldval & mask) >> shift; \ + \ + actual_newval = (actual_oldval & ~mask) \ + | (((unsigned int) newval << shift) & mask); \ + \ + fail = __kernel_cmpxchg (actual_oldval, actual_newval, \ + wordptr); \ + \ + if (__builtin_expect (!fail, 1)) \ + return oldval; \ + } \ + } + +SUBWORD_VAL_CAS (unsigned short, 2) +SUBWORD_VAL_CAS (unsigned char, 1) + +typedef unsigned char bool; + +bool HIDDEN +__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval) +{ + int failure = __kernel_cmpxchg (oldval, newval, ptr); + return (failure == 0); +} + +#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \ + bool HIDDEN \ + __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ + TYPE newval) \ + { \ + TYPE actual_oldval \ + = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \ + return (oldval == actual_oldval); \ + } + +SUBWORD_BOOL_CAS (unsigned short, 2) +SUBWORD_BOOL_CAS (unsigned char, 1) + +void HIDDEN +__sync_synchronize (void) +{ + __kernel_dmb (); +} + +int HIDDEN +__sync_lock_test_and_set_4 (int *ptr, int val) +{ + int failure, oldval; + + do { + oldval = *ptr; + failure = __kernel_cmpxchg (oldval, val, ptr); + } while (failure != 0); + + return oldval; +} + +#define SUBWORD_TEST_AND_SET(TYPE, WIDTH) \ + TYPE HIDDEN \ + __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \ + { \ + int failure; \ + unsigned int oldval, newval, shift, mask; \ + int *wordptr = (int *) ((unsigned int) ptr & ~3); \ + \ + shift = (((unsigned int) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ + mask = MASK_##WIDTH << shift; \ + \ + do { \ + oldval = *wordptr; \ + newval = (oldval & ~mask) \ + | (((unsigned int) val << shift) & mask); \ + failure = __kernel_cmpxchg (oldval, newval, wordptr); \ + } while (failure != 0); \ + \ + return (oldval & mask) >> shift; \ + } + +SUBWORD_TEST_AND_SET (unsigned short, 2) +SUBWORD_TEST_AND_SET (unsigned char, 1) + +#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \ + void HIDDEN \ + __sync_lock_release_##WIDTH (TYPE *ptr) \ + { \ + /* All writes before this point must be seen before we release \ + the lock itself. */ \ + __kernel_dmb (); \ + *ptr = 0; \ + } + +SYNC_LOCK_RELEASE (long long, 8) +SYNC_LOCK_RELEASE (int, 4) +SYNC_LOCK_RELEASE (short, 2) +SYNC_LOCK_RELEASE (char, 1) diff --git a/libgcc/config/arm/t-bpabi b/libgcc/config/arm/t-bpabi index 8787285..e79cbd7 100644 --- a/libgcc/config/arm/t-bpabi +++ b/libgcc/config/arm/t-bpabi @@ -1,6 +1,12 @@ # Add the bpabi.S functions. LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod +# Add the BPABI C functions. +LIB2ADD += $(srcdir)/config/arm/bpabi.c \ + $(srcdir)/config/arm/unaligned-funcs.c + +LIB2ADD_ST += $(srcdir)/config/arm/fp16.c + LIB2ADDEH = $(srcdir)/config/arm/unwind-arm.c \ $(srcdir)/config/arm/libunwind.S \ $(srcdir)/config/arm/pr-support.c $(srcdir)/unwind-c.c diff --git a/libgcc/config/arm/t-elf b/libgcc/config/arm/t-elf index fab32e4..414484e 100644 --- a/libgcc/config/arm/t-elf +++ b/libgcc/config/arm/t-elf @@ -11,3 +11,8 @@ LIB1ASMFUNCS += _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func \ _arm_cmpsf2 _arm_unordsf2 _arm_fixsfsi _arm_fixunssfsi \ _arm_floatdidf _arm_floatdisf _arm_floatundidf _arm_floatundisf \ _clzsi2 _clzdi2 + +# Currently there is a bug somewhere in GCC's alias analysis +# or scheduling code that is breaking _fpmul_parts in fp-bit.c. +# Disabling function inlining is a workaround for this problem. +HOST_LIBGCC2_CFLAGS = -fno-inline diff --git a/libgcc/config/arm/t-linux b/libgcc/config/arm/t-linux index a154f77..4c1efeb 100644 --- a/libgcc/config/arm/t-linux +++ b/libgcc/config/arm/t-linux @@ -1,3 +1,7 @@ LIB1ASMSRC = arm/lib1funcs.S LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \ _arm_addsubdf3 _arm_addsubsf3 + +# Just for these, we omit the frame pointer since it makes such a big +# difference. +HOST_LIBGCC2_CFLAGS += -fomit-frame-pointer diff --git a/libgcc/config/arm/t-linux-eabi b/libgcc/config/arm/t-linux-eabi index dfc9197..a03e2b6 100644 --- a/libgcc/config/arm/t-linux-eabi +++ b/libgcc/config/arm/t-linux-eabi @@ -1,2 +1,5 @@ # Use a version of div0 which raises SIGFPE, and a special __clear_cache. LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx _clear_cache + +LIB2ADD_ST += $(srcdir)/config/arm/linux-atomic.c \ + $(srcdir)/config/arm/linux-atomic-64bit.c diff --git a/libgcc/config/arm/t-netbsd b/libgcc/config/arm/t-netbsd new file mode 100644 index 0000000..95358f9 --- /dev/null +++ b/libgcc/config/arm/t-netbsd @@ -0,0 +1,7 @@ +# Just for these, we omit the frame pointer since it makes such a big +# difference. It is then pointless adding debugging. +HOST_LIBGCC2_CFLAGS += -fomit-frame-pointer + +LIBGCC2_DEBUG_CFLAGS = -g0 + +LIB2ADD += $(srcdir)/floatunsidf.c $(srcdir)/floatunsisf.c diff --git a/libgcc/config/arm/t-strongarm-elf b/libgcc/config/arm/t-strongarm-elf index cd9f966..369a839 100644 --- a/libgcc/config/arm/t-strongarm-elf +++ b/libgcc/config/arm/t-strongarm-elf @@ -1 +1,6 @@ LIB1ASMFUNCS += _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func _clzsi2 _clzdi2 + +# Currently there is a bug somewhere in GCC's alias analysis +# or scheduling code that is breaking _fpmul_parts in fp-bit.c. +# Disabling function inlining is a workaround for this problem. +HOST_LIBGCC2_CFLAGS = -fno-inline diff --git a/libgcc/config/arm/t-symbian b/libgcc/config/arm/t-symbian index 1989696..06d98fa 100644 --- a/libgcc/config/arm/t-symbian +++ b/libgcc/config/arm/t-symbian @@ -12,5 +12,8 @@ LIB1ASMFUNCS += \ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \ _fixsfsi _fixunssfsi +# Include half-float helpers. +LIB2ADD_ST += $(srcdir)/config/arm/fp16.c + # Include the gcc personality routine LIB2ADDEH = $(srcdir)/unwind-c.c $(srcdir)/config/arm/pr-support.c diff --git a/libgcc/config/arm/unaligned-funcs.c b/libgcc/config/arm/unaligned-funcs.c new file mode 100644 index 0000000..4e684f4 --- /dev/null +++ b/libgcc/config/arm/unaligned-funcs.c @@ -0,0 +1,57 @@ +/* EABI unaligned read/write functions. + + Copyright (C) 2005, 2009 Free Software Foundation, Inc. + Contributed by CodeSourcery, LLC. + + This file 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. + + This file 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/>. */ + +int __aeabi_uread4 (void *); +int __aeabi_uwrite4 (int, void *); +long long __aeabi_uread8 (void *); +long long __aeabi_uwrite8 (long long, void *); + +struct __attribute__((packed)) u4 { int data; }; +struct __attribute__((packed)) u8 { long long data; }; + +int +__aeabi_uread4 (void *ptr) +{ + return ((struct u4 *) ptr)->data; +} + +int +__aeabi_uwrite4 (int data, void *ptr) +{ + ((struct u4 *) ptr)->data = data; + return data; +} + +long long +__aeabi_uread8 (void *ptr) +{ + return ((struct u8 *) ptr)->data; +} + +long long +__aeabi_uwrite8 (long long data, void *ptr) +{ + ((struct u8 *) ptr)->data = data; + return data; +} diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr index f1c114a..a669f61 100644 --- a/libgcc/config/avr/t-avr +++ b/libgcc/config/avr/t-avr @@ -46,6 +46,14 @@ LIB1ASMFUNCS = \ _lshrdi3 \ _fmul _fmuls _fmulsu +LIB2FUNCS_EXCLUDE = \ + _clz + +# We do not have the DF type. +# Most of the C functions in libgcc2 use almost all registers, +# so use -mcall-prologues for smaller code size. +HOST_LIBGCC2_CFLAGS = -DDF=SF -Dinhibit_libc -mcall-prologues -Os + # Extra 16-bit integer functions. intfuncs16 = _absvXX2 _addvXX3 _subvXX3 _mulvXX3 _negvXX2 _clrsbXX2 diff --git a/libgcc/config/bfin/t-crtstuff b/libgcc/config/bfin/t-crtstuff index 7b343e2..eee12eb 100644 --- a/libgcc/config/bfin/t-crtstuff +++ b/libgcc/config/bfin/t-crtstuff @@ -1 +1 @@ -CRTSTUFF_T_CFLAGS = -fpic +CRTSTUFF_T_CFLAGS = $(PICFLAG) diff --git a/libgcc/config/bfin/t-elf b/libgcc/config/bfin/t-elf new file mode 100644 index 0000000..cb243e6 --- /dev/null +++ b/libgcc/config/bfin/t-elf @@ -0,0 +1 @@ +HOST_LIBGCC2_CFLAGS = $(PICFLAG) diff --git a/libgcc/config/c6x/eqd.c b/libgcc/config/c6x/eqd.c new file mode 100644 index 0000000..d6b3201 --- /dev/null +++ b/libgcc/config/c6x/eqd.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a == b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007,2011 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/double.h> + +CMPtype __c6xabi_eqd(DFtype a, DFtype b) +{ + FP_DECL_EX; + FP_DECL_D(A); FP_DECL_D(B); + CMPtype r; + + FP_UNPACK_RAW_D(A, a); + FP_UNPACK_RAW_D(B, b); + FP_CMP_EQ_D(r, A, B); + if (r && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return !r; +} diff --git a/libgcc/config/c6x/eqf.c b/libgcc/config/c6x/eqf.c new file mode 100644 index 0000000..ee6dafc --- /dev/null +++ b/libgcc/config/c6x/eqf.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a == b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007,2011 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/single.h> + +CMPtype __c6xabi_eqf(SFtype a, SFtype b) +{ + FP_DECL_EX; + FP_DECL_S(A); FP_DECL_S(B); + CMPtype r; + + FP_UNPACK_RAW_S(A, a); + FP_UNPACK_RAW_S(B, b); + FP_CMP_EQ_S(r, A, B); + if (r && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return !r; +} diff --git a/libgcc/config/c6x/ged.c b/libgcc/config/c6x/ged.c new file mode 100644 index 0000000..2089904 --- /dev/null +++ b/libgcc/config/c6x/ged.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a >= b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007,2011 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/double.h> + +CMPtype __c6xabi_ged(DFtype a, DFtype b) +{ + FP_DECL_EX; + FP_DECL_D(A); FP_DECL_D(B); + CMPtype r; + + FP_UNPACK_RAW_D(A, a); + FP_UNPACK_RAW_D(B, b); + FP_CMP_D(r, A, B, -2); + if (r == -2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return r >= 0; +} diff --git a/libgcc/config/c6x/gef.c b/libgcc/config/c6x/gef.c new file mode 100644 index 0000000..ce4c1c0 --- /dev/null +++ b/libgcc/config/c6x/gef.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a >= b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/single.h> + +CMPtype __c6xabi_gef(SFtype a, SFtype b) +{ + FP_DECL_EX; + FP_DECL_S(A); FP_DECL_S(B); + CMPtype r; + + FP_UNPACK_RAW_S(A, a); + FP_UNPACK_RAW_S(B, b); + FP_CMP_S(r, A, B, -2); + if (r == -2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return r >= 0; +} diff --git a/libgcc/config/c6x/gtd.c b/libgcc/config/c6x/gtd.c new file mode 100644 index 0000000..6d45aef --- /dev/null +++ b/libgcc/config/c6x/gtd.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a > b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007,2011 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/double.h> + +CMPtype __c6xabi_gtd(DFtype a, DFtype b) +{ + FP_DECL_EX; + FP_DECL_D(A); FP_DECL_D(B); + CMPtype r; + + FP_UNPACK_RAW_D(A, a); + FP_UNPACK_RAW_D(B, b); + FP_CMP_D(r, A, B, -2); + if (r == -2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return r > 0; +} diff --git a/libgcc/config/c6x/gtf.c b/libgcc/config/c6x/gtf.c new file mode 100644 index 0000000..c6a108a --- /dev/null +++ b/libgcc/config/c6x/gtf.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a > b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007,2011 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/single.h> + +CMPtype __c6xabi_gtf(SFtype a, SFtype b) +{ + FP_DECL_EX; + FP_DECL_S(A); FP_DECL_S(B); + CMPtype r; + + FP_UNPACK_RAW_S(A, a); + FP_UNPACK_RAW_S(B, b); + FP_CMP_S(r, A, B, -2); + if (r == -2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return r > 0; +} diff --git a/libgcc/config/c6x/led.c b/libgcc/config/c6x/led.c new file mode 100644 index 0000000..c99e29e --- /dev/null +++ b/libgcc/config/c6x/led.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a <= b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007,2011 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/double.h> + +CMPtype __c6xabi_led(DFtype a, DFtype b) +{ + FP_DECL_EX; + FP_DECL_D(A); FP_DECL_D(B); + CMPtype r; + + FP_UNPACK_RAW_D(A, a); + FP_UNPACK_RAW_D(B, b); + FP_CMP_D(r, A, B, 2); + if (r == 2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return r <= 0; +} diff --git a/libgcc/config/c6x/lef.c b/libgcc/config/c6x/lef.c new file mode 100644 index 0000000..ce2c16f --- /dev/null +++ b/libgcc/config/c6x/lef.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a <= b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007,2011 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/single.h> + +CMPtype __c6xabi_lef(SFtype a, SFtype b) +{ + FP_DECL_EX; + FP_DECL_S(A); FP_DECL_S(B); + CMPtype r; + + FP_UNPACK_RAW_S(A, a); + FP_UNPACK_RAW_S(B, b); + FP_CMP_S(r, A, B, 2); + if (r == 2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return r <= 0; +} diff --git a/libgcc/config/c6x/ltd.c b/libgcc/config/c6x/ltd.c new file mode 100644 index 0000000..d4de2586 --- /dev/null +++ b/libgcc/config/c6x/ltd.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a < b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007,2011 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/double.h> + +CMPtype __c6xabi_ltd(DFtype a, DFtype b) +{ + FP_DECL_EX; + FP_DECL_D(A); FP_DECL_D(B); + CMPtype r; + + FP_UNPACK_RAW_D(A, a); + FP_UNPACK_RAW_D(B, b); + FP_CMP_D(r, A, B, 2); + if (r == 2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return r < 0; +} diff --git a/libgcc/config/c6x/ltf.c b/libgcc/config/c6x/ltf.c new file mode 100644 index 0000000..2fe15b9 --- /dev/null +++ b/libgcc/config/c6x/ltf.c @@ -0,0 +1,47 @@ +/* Software floating-point emulation. + Return 1 iff a < b, 0 otherwise. + Copyright (C) 1997,1999,2006,2007,2011 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + This file 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GCC; see the file COPYING.LIB. If not see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp/soft-fp.h> +#include <soft-fp/single.h> + +CMPtype __c6xabi_ltf(SFtype a, SFtype b) +{ + FP_DECL_EX; + FP_DECL_S(A); FP_DECL_S(B); + CMPtype r; + + FP_UNPACK_RAW_S(A, a); + FP_UNPACK_RAW_S(B, b); + FP_CMP_S(r, A, B, 2); + if (r == 2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) + FP_SET_EXCEPTION(FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; + + return r < 0; +} diff --git a/libgcc/config/c6x/t-elf b/libgcc/config/c6x/t-elf index e01c410..2ee6a957 100644 --- a/libgcc/config/c6x/t-elf +++ b/libgcc/config/c6x/t-elf @@ -6,6 +6,22 @@ LIB1ASMFUNCS = _divsi3 _udivsi3 _umodsi3 _modsi3 _udivmodsi4 _divmodsi4 LIB1ASMFUNCS += _strasgi _strasgi_64plus _clzsi2 _clzdi2 _clz LIB1ASMFUNCS += _push_rts _pop_rts _call_stub +LIB2FUNCS_EXCLUDE = _cmpdi2 _ucmpdi2 _gcc_bcmp _eprintf _clzsi _clzdi + +LIB2ADD = $(srcdir)/config/c6x/gef.c \ + $(srcdir)/config/c6x/gtf.c \ + $(srcdir)/config/c6x/lef.c \ + $(srcdir)/config/c6x/ltf.c \ + $(srcdir)/config/c6x/eqf.c \ + $(srcdir)/config/c6x/ged.c \ + $(srcdir)/config/c6x/gtd.c \ + $(srcdir)/config/c6x/led.c \ + $(srcdir)/config/c6x/ltd.c \ + $(srcdir)/config/c6x/eqd.c + +# Avoid failures when the user's GOT becomes too large. +HOST_LIBGCC2_CFLAGS = -msdata=none + # Assemble startup files. crti.o: $(srcdir)/config/c6x/crti.S $(crt_compile) -c $(CRTSTUFF_T_CFLAGS) $< diff --git a/libgcc/config/c6x/t-uclinux b/libgcc/config/c6x/t-uclinux index 15fb9a1..72a170a 100644 --- a/libgcc/config/c6x/t-uclinux +++ b/libgcc/config/c6x/t-uclinux @@ -1 +1,3 @@ -CRTSTUFF_T_CFLAGS += -fPIC +HOST_LIBGCC2_CFLAGS += -msdata=none + +CRTSTUFF_T_CFLAGS += $(PICFLAG) diff --git a/libgcc/config/cris/arit.c b/libgcc/config/cris/arit.c new file mode 100644 index 0000000..32255f9 --- /dev/null +++ b/libgcc/config/cris/arit.c @@ -0,0 +1,304 @@ +/* Signed and unsigned multiplication and division and modulus for CRIS. + Contributed by Axis Communications. + Written by Hans-Peter Nilsson <hp@axis.se>, c:a 1992. + + Copyright (C) 1998, 1999, 2000, 2001, 2002, + 2005, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This file 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/>. */ + + +/* Note that we provide prototypes for all "const" functions, to attach + the const attribute. This is necessary in 2.7.2 - adding the + attribute to the function *definition* is a syntax error. + This did not work with e.g. 2.1; back then, the return type had to + be "const". */ + +#include "config.h" + +#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 3 +#define LZ(v) __builtin_clz (v) +#endif + + +#if defined (L_udivsi3) || defined (L_divsi3) || defined (L_umodsi3) \ + || defined (L_modsi3) +/* Result type of divmod worker function. */ +struct quot_rem + { + long quot; + long rem; + }; + +/* This is the worker function for div and mod. It is inlined into the + respective library function. Parameter A must have bit 31 == 0. */ + +static __inline__ struct quot_rem +do_31div (unsigned long a, unsigned long b) + __attribute__ ((__const__, __always_inline__)); + +static __inline__ struct quot_rem +do_31div (unsigned long a, unsigned long b) +{ + /* Adjust operands and result if a is 31 bits. */ + long extra = 0; + int quot_digits = 0; + + if (b == 0) + { + struct quot_rem ret; + ret.quot = 0xffffffff; + ret.rem = 0xffffffff; + return ret; + } + + if (a < b) + return (struct quot_rem) { 0, a }; + +#ifdef LZ + if (b <= a) + { + quot_digits = LZ (b) - LZ (a); + quot_digits += (a >= (b << quot_digits)); + b <<= quot_digits; + } +#else + while (b <= a) + { + b <<= 1; + quot_digits++; + } +#endif + + /* Is a 31 bits? Note that bit 31 is handled by the caller. */ + if (a & 0x40000000) + { + /* Then make b:s highest bit max 0x40000000, because it must have + been 0x80000000 to be 1 bit higher than a. */ + b >>= 1; + + /* Adjust a to be maximum 0x3fffffff, i.e. two upper bits zero. */ + if (a >= b) + { + a -= b; + extra = 1 << (quot_digits - 1); + } + else + { + a -= b >> 1; + + /* Remember that we adjusted a by subtracting b * 2 ** Something. */ + extra = 1 << quot_digits; + } + + /* The number of quotient digits will be one less, because + we just adjusted b. */ + quot_digits--; + } + + /* Now do the division part. */ + + /* Subtract b and add ones to the right when a >= b + i.e. "a - (b - 1) == (a - b) + 1". */ + b--; + +#define DS __asm__ ("dstep %2,%0" : "=r" (a) : "0" (a), "r" (b)) + + switch (quot_digits) + { + case 32: DS; case 31: DS; case 30: DS; case 29: DS; + case 28: DS; case 27: DS; case 26: DS; case 25: DS; + case 24: DS; case 23: DS; case 22: DS; case 21: DS; + case 20: DS; case 19: DS; case 18: DS; case 17: DS; + case 16: DS; case 15: DS; case 14: DS; case 13: DS; + case 12: DS; case 11: DS; case 10: DS; case 9: DS; + case 8: DS; case 7: DS; case 6: DS; case 5: DS; + case 4: DS; case 3: DS; case 2: DS; case 1: DS; + case 0:; + } + + { + struct quot_rem ret; + ret.quot = (a & ((1 << quot_digits) - 1)) + extra; + ret.rem = a >> quot_digits; + return ret; + } +} + +#ifdef L_udivsi3 +unsigned long +__Udiv (unsigned long a, unsigned long b) __attribute__ ((__const__)); + +unsigned long +__Udiv (unsigned long a, unsigned long b) +{ + long extra = 0; + + /* Adjust operands and result, if a and/or b is 32 bits. */ + /* Effectively: b & 0x80000000. */ + if ((long) b < 0) + return a >= b; + + /* Effectively: a & 0x80000000. */ + if ((long) a < 0) + { + int tmp = 0; + + if (b == 0) + return 0xffffffff; +#ifdef LZ + tmp = LZ (b); +#else + for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--) + ; + + tmp = 31 - tmp; +#endif + + if ((b << tmp) > a) + { + extra = 1 << (tmp-1); + a -= b << (tmp - 1); + } + else + { + extra = 1 << tmp; + a -= b << tmp; + } + } + + return do_31div (a, b).quot+extra; +} +#endif /* L_udivsi3 */ + +#ifdef L_divsi3 +long +__Div (long a, long b) __attribute__ ((__const__)); + +long +__Div (long a, long b) +{ + long extra = 0; + long sign = (b < 0) ? -1 : 1; + + /* We need to handle a == -2147483648 as expected and must while + doing that avoid producing a sequence like "abs (a) < 0" as GCC + may optimize out the test. That sequence may not be obvious as + we call inline functions. Testing for a being negative and + handling (presumably much rarer than positive) enables us to get + a bit of optimization for an (accumulated) reduction of the + penalty of the 0x80000000 special-case. */ + if (a < 0) + { + sign = -sign; + + if ((a & 0x7fffffff) == 0) + { + /* We're at 0x80000000. Tread carefully. */ + a -= b * sign; + extra = sign; + } + a = -a; + } + + /* We knowingly penalize pre-v10 models by multiplication with the + sign. */ + return sign * do_31div (a, __builtin_labs (b)).quot + extra; +} +#endif /* L_divsi3 */ + + +#ifdef L_umodsi3 +unsigned long +__Umod (unsigned long a, unsigned long b) __attribute__ ((__const__)); + +unsigned long +__Umod (unsigned long a, unsigned long b) +{ + /* Adjust operands and result if a and/or b is 32 bits. */ + if ((long) b < 0) + return a >= b ? a - b : a; + + if ((long) a < 0) + { + int tmp = 0; + + if (b == 0) + return a; +#ifdef LZ + tmp = LZ (b); +#else + for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--) + ; + tmp = 31 - tmp; +#endif + + if ((b << tmp) > a) + { + a -= b << (tmp - 1); + } + else + { + a -= b << tmp; + } + } + + return do_31div (a, b).rem; +} +#endif /* L_umodsi3 */ + +#ifdef L_modsi3 +long +__Mod (long a, long b) __attribute__ ((__const__)); + +long +__Mod (long a, long b) +{ + long sign = 1; + + /* We need to handle a == -2147483648 as expected and must while + doing that avoid producing a sequence like "abs (a) < 0" as GCC + may optimize out the test. That sequence may not be obvious as + we call inline functions. Testing for a being negative and + handling (presumably much rarer than positive) enables us to get + a bit of optimization for an (accumulated) reduction of the + penalty of the 0x80000000 special-case. */ + if (a < 0) + { + sign = -1; + if ((a & 0x7fffffff) == 0) + /* We're at 0x80000000. Tread carefully. */ + a += __builtin_labs (b); + a = -a; + } + + return sign * do_31div (a, __builtin_labs (b)).rem; +} +#endif /* L_modsi3 */ +#endif /* L_udivsi3 || L_divsi3 || L_umodsi3 || L_modsi3 */ + +/* + * Local variables: + * eval: (c-set-style "gnu") + * indent-tabs-mode: t + * End: + */ diff --git a/libgcc/config/cris/mulsi3.S b/libgcc/config/cris/mulsi3.S new file mode 100644 index 0000000..76dfb63 --- /dev/null +++ b/libgcc/config/cris/mulsi3.S @@ -0,0 +1,255 @@ +;; Copyright (C) 2001, 2004 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it under +;; the terms of the GNU General Public License as published by the Free +;; Software Foundation; either version 3, or (at your option) any later +;; version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY +;; WARRANTY; without even the implied warranty of MERCHANTABILITY or +;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +;; for more details. +;; +;; Under Section 7 of GPL version 3, you are granted additional +;; permissions described in the GCC Runtime Library Exception, version +;; 3.1, as published by the Free Software Foundation. +;; +;; You should have received a copy of the GNU General Public License and +;; a copy of the GCC Runtime Library Exception along with this program; +;; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +;; <http://www.gnu.org/licenses/>. +;; +;; This code used to be expanded through interesting expansions in +;; the machine description, compiled from this code: +;; +;; #ifdef L_mulsi3 +;; long __Mul (unsigned long a, unsigned long b) __attribute__ ((__const__)); +;; +;; /* This must be compiled with the -mexpand-mul flag, to synthesize the +;; multiplication from the mstep instructions. The check for +;; smaller-size multiplication pays off in the order of .5-10%; +;; estimated median 1%, depending on application. +;; FIXME: It can be further optimized if we go to assembler code, as +;; gcc 2.7.2 adds a few unnecessary instructions and does not put the +;; basic blocks in optimal order. */ +;; long +;; __Mul (unsigned long a, unsigned long b) +;; { +;; #if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10 +;; /* In case other code is compiled without -march=v10, they will +;; contain calls to __Mul, regardless of flags at link-time. The +;; "else"-code below will work, but is unnecessarily slow. This +;; sometimes cuts a few minutes off from simulation time by just +;; returning a "mulu.d". */ +;; return a * b; +;; #else +;; unsigned long min; +;; +;; /* Get minimum via the bound insn. */ +;; min = a < b ? a : b; +;; +;; /* Can we omit computation of the high part? */ +;; if (min > 65535) +;; /* No. Perform full multiplication. */ +;; return a * b; +;; else +;; { +;; /* Check if both operands are within 16 bits. */ +;; unsigned long max; +;; +;; /* Get maximum, by knowing the minimum. +;; This will partition a and b into max and min. +;; This is not currently something GCC understands, +;; so do this trick by asm. */ +;; __asm__ ("xor %1,%0\n\txor %2,%0" +;; : "=r" (max) +;; : "r" (b), "r" (a), "0" (min)); +;; +;; if (max > 65535) +;; /* Make GCC understand that only the low part of "min" will be +;; used. */ +;; return max * (unsigned short) min; +;; else +;; /* Only the low parts of both operands are necessary. */ +;; return ((unsigned short) max) * (unsigned short) min; +;; } +;; #endif /* not __CRIS_arch_version >= 10 */ +;; } +;; #endif /* L_mulsi3 */ +;; +;; That approach was abandoned since the caveats outweighted the +;; benefits. The expand-multiplication machinery is also removed, so you +;; can't do this anymore. +;; +;; For doubters of there being any benefits, some where: insensitivity to: +;; - ABI changes (mostly for experimentation) +;; - assembler syntax differences (mostly debug format). +;; - insn scheduling issues. +;; Most ABI experiments will presumably happen with arches with mul insns, +;; so that argument doesn't really hold anymore, and it's unlikely there +;; being new arch variants needing insn scheduling and not having mul +;; insns. + +;; ELF and a.out have different syntax for local labels: the "wrong" +;; one may not be omitted from the object. +#undef L +#ifdef __AOUT__ +# define L(x) x +#else +# define L(x) .x +#endif + + .global ___Mul + .type ___Mul,@function +___Mul: +#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10 +;; Can't have the mulu.d last on a cache-line (in the delay-slot of the +;; "ret"), due to hardware bug. See documentation for -mmul-bug-workaround. +;; Not worthwhile to conditionalize here. + .p2alignw 2,0x050f + mulu.d $r11,$r10 + ret + nop +#else + move.d $r10,$r12 + move.d $r11,$r9 + bound.d $r12,$r9 + cmpu.w 65535,$r9 + bls L(L3) + move.d $r12,$r13 + + movu.w $r11,$r9 + lslq 16,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + mstep $r9,$r13 + clear.w $r10 + test.d $r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + movu.w $r12,$r12 + move.d $r11,$r9 + clear.w $r9 + test.d $r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + mstep $r12,$r9 + add.w $r9,$r10 + lslq 16,$r10 + ret + add.d $r13,$r10 + +L(L3): + move.d $r9,$r10 + xor $r11,$r10 + xor $r12,$r10 + cmpu.w 65535,$r10 + bls L(L5) + movu.w $r9,$r13 + + movu.w $r13,$r13 + move.d $r10,$r9 + lslq 16,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + mstep $r13,$r9 + clear.w $r10 + test.d $r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + mstep $r13,$r10 + lslq 16,$r10 + ret + add.d $r9,$r10 + +L(L5): + movu.w $r9,$r9 + lslq 16,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + mstep $r9,$r10 + ret + mstep $r9,$r10 +#endif +L(Lfe1): + .size ___Mul,L(Lfe1)-___Mul diff --git a/libgcc/config/cris/t-cris b/libgcc/config/cris/t-cris new file mode 100644 index 0000000..b582974 --- /dev/null +++ b/libgcc/config/cris/t-cris @@ -0,0 +1,10 @@ +LIB2ADD = _udivsi3.c _divsi3.c _umodsi3.c _modsi3.c + +# The fixed-point arithmetic code is in one file, arit.c, +# similar to libgcc2.c (or the old libgcc1.c). We need to +# "split it up" with one file per define. +$(LIB2ADD): $(srcdir)/config/cris/arit.c + name=`echo $@ | sed -e 's,.*/,,' | sed -e 's,.c$$,,'`; \ + echo "#define L$$name" > tmp-$@ \ + && echo '#include "$<"' >> tmp-$@ \ + && mv -f tmp-$@ $@ diff --git a/libgcc/config/cris/t-elfmulti b/libgcc/config/cris/t-elfmulti index 3bb8ecf..b180521 100644 --- a/libgcc/config/cris/t-elfmulti +++ b/libgcc/config/cris/t-elfmulti @@ -1 +1,3 @@ +LIB2ADD_ST = $(srcdir)/config/cris/mulsi3.S + CRTSTUFF_T_CFLAGS = -moverride-best-lib-options diff --git a/libgcc/config/cris/t-linux b/libgcc/config/cris/t-linux index 26555fd..8c7f4d4 100644 --- a/libgcc/config/cris/t-linux +++ b/libgcc/config/cris/t-linux @@ -1,4 +1,2 @@ -CRTSTUFF_T_CFLAGS_S = $(HOST_LIBGCC2_CFLAGS) - # Override t-linux default. SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/cris/libgcc-glibc.ver diff --git a/libgcc/config/darwin-64.c b/libgcc/config/darwin-64.c new file mode 100644 index 0000000..a012e9d --- /dev/null +++ b/libgcc/config/darwin-64.c @@ -0,0 +1,72 @@ +/* Functions shipped in the ppc64 and x86_64 version of libgcc_s.1.dylib + in older Mac OS X versions, preserved for backwards compatibility. + Copyright (C) 2006, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#if defined (__ppc64__) || defined (__x86_64__) +/* Many of these functions have probably never been used by anyone + anywhere on these targets, but it's hard to prove this, so they're defined + here. None are actually necessary, as demonstrated below by defining + each function using the operation it implements. */ + +typedef long DI; +typedef unsigned long uDI; +typedef int SI; +typedef unsigned int uSI; +typedef int word_type __attribute__ ((mode (__word__))); + +DI __ashldi3 (DI x, word_type c); +DI __ashrdi3 (DI x, word_type c); +int __clzsi2 (uSI x); +word_type __cmpdi2 (DI x, DI y); +int __ctzsi2 (uSI x); +DI __divdi3 (DI x, DI y); +uDI __lshrdi3 (uDI x, word_type c); +DI __moddi3 (DI x, DI y); +DI __muldi3 (DI x, DI y); +DI __negdi2 (DI x); +int __paritysi2 (uSI x); +int __popcountsi2 (uSI x); +word_type __ucmpdi2 (uDI x, uDI y); +uDI __udivdi3 (uDI x, uDI y); +uDI __udivmoddi4 (uDI x, uDI y, uDI *r); +uDI __umoddi3 (uDI x, uDI y); + +DI __ashldi3 (DI x, word_type c) { return x << c; } +DI __ashrdi3 (DI x, word_type c) { return x >> c; } +int __clzsi2 (uSI x) { return __builtin_clz (x); } +word_type __cmpdi2 (DI x, DI y) { return x < y ? 0 : x == y ? 1 : 2; } +int __ctzsi2 (uSI x) { return __builtin_ctz (x); } +DI __divdi3 (DI x, DI y) { return x / y; } +uDI __lshrdi3 (uDI x, word_type c) { return x >> c; } +DI __moddi3 (DI x, DI y) { return x % y; } +DI __muldi3 (DI x, DI y) { return x * y; } +DI __negdi2 (DI x) { return -x; } +int __paritysi2 (uSI x) { return __builtin_parity (x); } +int __popcountsi2 (uSI x) { return __builtin_popcount (x); } +word_type __ucmpdi2 (uDI x, uDI y) { return x < y ? 0 : x == y ? 1 : 2; } +uDI __udivdi3 (uDI x, uDI y) { return x / y; } +uDI __udivmoddi4 (uDI x, uDI y, uDI *r) { *r = x % y; return x / y; } +uDI __umoddi3 (uDI x, uDI y) { return x % y; } + +#endif /* __ppc64__ || __x86_64__ */ diff --git a/libgcc/config/darwin-crt3.c b/libgcc/config/darwin-crt3.c index 9b64f2a..5ef0054 100644 --- a/libgcc/config/darwin-crt3.c +++ b/libgcc/config/darwin-crt3.c @@ -1,5 +1,5 @@ /* __cxa_atexit backwards-compatibility support for Darwin. - Copyright (C) 2006, 2009 Free Software Foundation, Inc. + Copyright (C) 2006, 2009, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -25,10 +25,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Don't do anything if we are compiling for a kext multilib. */ #ifdef __PIC__ -/* It is incorrect to include config.h here, because this file is being - compiled for the target, and hence definitions concerning only the host - do not apply. */ - #include "tconfig.h" #include "tsystem.h" diff --git a/libgcc/config/frv/cmovd.c b/libgcc/config/frv/cmovd.c new file mode 100644 index 0000000..e46070a --- /dev/null +++ b/libgcc/config/frv/cmovd.c @@ -0,0 +1,51 @@ +/* Move double-word library function. + Copyright (C) 2000, 2003, 2009 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GCC. + + GCC is free software ; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY ; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +void +__cmovd (long long *dest, const long long *src, unsigned len) +{ + unsigned i; + unsigned num = len >> 3; + unsigned xlen = len & ~7; + char *dest_byte = (char *)dest; + const char *src_byte = (const char *)src; + + if (dest_byte < src_byte || dest_byte > src_byte+len) + { + for (i = 0; i < num; i++) + dest[i] = src[i]; + + while (len > xlen) + { + dest_byte[xlen] = src_byte[xlen]; + xlen++; + } + } + else + { + while (len-- > 0) + dest_byte[len] = src_byte[len]; + } +} diff --git a/libgcc/config/frv/cmovh.c b/libgcc/config/frv/cmovh.c new file mode 100644 index 0000000..6b0901d --- /dev/null +++ b/libgcc/config/frv/cmovh.c @@ -0,0 +1,47 @@ +/* Move half-word library function. + Copyright (C) 2000, 2003, 2009 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GCC. + + GCC is free software ; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY ; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +void +__cmovh (short *dest, const short *src, unsigned len) +{ + unsigned i; + unsigned num = len >> 1; + char *dest_byte = (char *)dest; + const char *src_byte = (const char *)src; + + if (dest_byte < src_byte || dest_byte > src_byte+len) + { + for (i = 0; i < num; i++) + dest[i] = src[i]; + + if ((len & 1) != 0) + dest_byte[len-1] = src_byte[len-1]; + } + else + { + while (len-- > 0) + dest_byte[len] = src_byte[len]; + } +} diff --git a/libgcc/config/frv/cmovw.c b/libgcc/config/frv/cmovw.c new file mode 100644 index 0000000..f27db75 --- /dev/null +++ b/libgcc/config/frv/cmovw.c @@ -0,0 +1,51 @@ +/* Move word library function. + Copyright (C) 2000, 2003, 2009 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GCC. + + GCC is free software ; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY ; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +void +__cmovw (int *dest, const int *src, unsigned len) +{ + unsigned i; + unsigned num = len >> 2; + unsigned xlen = len & ~3; + char *dest_byte = (char *)dest; + const char *src_byte = (const char *)src; + + if (dest_byte < src_byte || dest_byte > src_byte+len) + { + for (i = 0; i < num; i++) + dest[i] = src[i]; + + while (len > xlen) + { + dest_byte[xlen] = src_byte[xlen]; + xlen++; + } + } + else + { + while (len-- > 0) + dest_byte[len] = src_byte[len]; + } +} diff --git a/libgcc/config/frv/modi.c b/libgcc/config/frv/modi.c new file mode 100644 index 0000000..d5a91fc --- /dev/null +++ b/libgcc/config/frv/modi.c @@ -0,0 +1,4 @@ +int __modi (int a, int b) +{ + return a % b; +} diff --git a/libgcc/config/frv/t-frv b/libgcc/config/frv/t-frv index 9773722..a4ff058 100644 --- a/libgcc/config/frv/t-frv +++ b/libgcc/config/frv/t-frv @@ -1,6 +1,16 @@ LIB1ASMSRC = frv/lib1funcs.S LIB1ASMFUNCS = _cmpll _cmpf _cmpd _addll _subll _andll _orll _xorll _notll _cmov +LIB2ADD = $(srcdir)/config/frv/cmovh.c \ + $(srcdir)/config/frv/cmovw.c \ + $(srcdir)/config/frv/cmovd.c \ + $(srcdir)/config/frv/modi.c \ + $(srcdir)/config/frv/umodi.c \ + $(srcdir)/config/frv/uitof.c \ + $(srcdir)/config/frv/uitod.c \ + $(srcdir)/config/frv/ulltof.c \ + $(srcdir)/config/frv/ulltod.c + # Compile two additional files that are linked with every program # linked using GCC on systems using COFF or ELF, for the sake of C++ # constructors. diff --git a/libgcc/config/frv/t-linux b/libgcc/config/frv/t-linux index 2b4fe3f..0240efe 100644 --- a/libgcc/config/frv/t-linux +++ b/libgcc/config/frv/t-linux @@ -1,3 +1,3 @@ -CRTSTUFF_T_CFLAGS = -fPIC +CRTSTUFF_T_CFLAGS = $(PICFLAG) SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/frv/libgcc-glibc.ver diff --git a/libgcc/config/frv/uitod.c b/libgcc/config/frv/uitod.c new file mode 100644 index 0000000..14290ab --- /dev/null +++ b/libgcc/config/frv/uitod.c @@ -0,0 +1,4 @@ +double __uitod (unsigned int a) +{ + return a; +} diff --git a/libgcc/config/frv/uitof.c b/libgcc/config/frv/uitof.c new file mode 100644 index 0000000..059bc7c --- /dev/null +++ b/libgcc/config/frv/uitof.c @@ -0,0 +1,4 @@ +float __uitof (unsigned int a) +{ + return a; +} diff --git a/libgcc/config/frv/ulltod.c b/libgcc/config/frv/ulltod.c new file mode 100644 index 0000000..e6bee12 --- /dev/null +++ b/libgcc/config/frv/ulltod.c @@ -0,0 +1,4 @@ +double __ulltod (unsigned long long a) +{ + return a; +} diff --git a/libgcc/config/frv/ulltof.c b/libgcc/config/frv/ulltof.c new file mode 100644 index 0000000..29cdfd4 --- /dev/null +++ b/libgcc/config/frv/ulltof.c @@ -0,0 +1,4 @@ +float __ulltof (unsigned long long a) +{ + return a; +} diff --git a/libgcc/config/frv/umodi.c b/libgcc/config/frv/umodi.c new file mode 100644 index 0000000..4ffe5ad --- /dev/null +++ b/libgcc/config/frv/umodi.c @@ -0,0 +1,4 @@ +unsigned int __umodi (unsigned int a, unsigned int b) +{ + return a % b; +} diff --git a/libgcc/config/h8300/clzhi2.c b/libgcc/config/h8300/clzhi2.c new file mode 100644 index 0000000..54db7b9 --- /dev/null +++ b/libgcc/config/h8300/clzhi2.c @@ -0,0 +1,35 @@ +/* The implementation of __clzhi2. + Copyright (C) 2003, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +int __clzhi2 (unsigned short x); + +int +__clzhi2 (unsigned short x) +{ + int i; + for (i = 0; i < 16; i++) + if (x & ((unsigned short) 1 << (15 - i))) + break; + return i; +} diff --git a/libgcc/config/h8300/ctzhi2.c b/libgcc/config/h8300/ctzhi2.c new file mode 100644 index 0000000..ba6f8e9 --- /dev/null +++ b/libgcc/config/h8300/ctzhi2.c @@ -0,0 +1,35 @@ +/* The implementation of __ctzhi2. + Copyright (C) 2003, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +int __ctzhi2 (unsigned short x); + +int +__ctzhi2 (unsigned short x) +{ + int i; + for (i = 0; i < 16; i++) + if (x & ((unsigned short) 1 << i)) + break; + return i; +} diff --git a/libgcc/config/h8300/fixunssfsi.c b/libgcc/config/h8300/fixunssfsi.c new file mode 100644 index 0000000..940d0c6 --- /dev/null +++ b/libgcc/config/h8300/fixunssfsi.c @@ -0,0 +1,41 @@ +/* More subroutines needed by GCC output code on some machines. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1989, 1992, 2001, 2002, 2003, 2004, 2009, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +/* The libgcc2.c implementation gets confused by our type setup and creates + a directly recursive call, so we do our own implementation. For + the H8/300, that's in lib1funcs.S, for H8/300H and H8S, it's here. */ + +#ifndef __H8300__ +long __fixunssfsi (float a); + +long +__fixunssfsi (float a) +{ + if (a >= (float) 32768L) + return (long) (a - 32768L) + 32768L; + return (long) a; +} +#endif diff --git a/libgcc/config/h8300/parityhi2.c b/libgcc/config/h8300/parityhi2.c new file mode 100644 index 0000000..d58cb89 --- /dev/null +++ b/libgcc/config/h8300/parityhi2.c @@ -0,0 +1,36 @@ +/* The implementation of __parityhi2. + Copyright (C) 2003, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +int __parityhi2 (unsigned short x); + +int +__parityhi2 (unsigned short x) +{ + int i; + int count = 0; + for (i = 0; i < 16; i++) + if (x & ((unsigned short) 1 << i)) + count++; + return count & 1; +} diff --git a/libgcc/config/h8300/popcounthi2.c b/libgcc/config/h8300/popcounthi2.c new file mode 100644 index 0000000..47be193 --- /dev/null +++ b/libgcc/config/h8300/popcounthi2.c @@ -0,0 +1,36 @@ +/* The implementation of __popcounthi2. + Copyright (C) 2003, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +int __popcounthi2 (unsigned short x); + +int +__popcounthi2 (unsigned short x) +{ + int i; + int count = 0; + for (i = 0; i < 16; i++) + if (x & ((unsigned short) 1 << i)) + count++; + return count; +} diff --git a/libgcc/config/h8300/t-h8300 b/libgcc/config/h8300/t-h8300 index 4602ff8..750529d 100644 --- a/libgcc/config/h8300/t-h8300 +++ b/libgcc/config/h8300/t-h8300 @@ -1,3 +1,13 @@ LIB1ASMSRC = h8300/lib1funcs.S LIB1ASMFUNCS = _cmpsi2 _ucmpsi2 _divhi3 _divsi3 _mulhi3 _mulsi3 \ _fixunssfsi_asm + +LIB2ADD = \ + $(srcdir)/config/h8300/clzhi2.c \ + $(srcdir)/config/h8300/ctzhi2.c \ + $(srcdir)/config/h8300/parityhi2.c \ + $(srcdir)/config/h8300/popcounthi2.c \ + $(srcdir)/config/h8300/fixunssfsi.c + +# We do not have DF type, so fake out the libgcc2 compilation. +HOST_LIBGCC2_CFLAGS = -DDF=SF diff --git a/libgcc/config/i386/gthr-win32.c b/libgcc/config/i386/gthr-win32.c new file mode 100644 index 0000000..46ecb0d --- /dev/null +++ b/libgcc/config/i386/gthr-win32.c @@ -0,0 +1,260 @@ +/* Implementation of W32-specific threads compatibility routines for + libgcc2. */ + +/* Copyright (C) 1999, 2000, 2002, 2004, 2008, 2009 Free Software Foundation, Inc. + Contributed by Mumit Khan <khan@xraylith.wisc.edu>. + Modified and moved to separate file by Danny Smith + <dannysmith@users.sourceforge.net>. + +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 <windows.h> +#ifndef __GTHREAD_HIDE_WIN32API +# define __GTHREAD_HIDE_WIN32API 1 +#endif +#undef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES +#define __GTHREAD_I486_INLINE_LOCK_PRIMITIVES +#include <gthr-win32.h> + +/* Windows32 threads specific definitions. The windows32 threading model + does not map well into pthread-inspired gcc's threading model, and so + there are caveats one needs to be aware of. + + 1. The destructor supplied to __gthread_key_create is ignored for + generic x86-win32 ports. This will certainly cause memory leaks + due to unreclaimed eh contexts (sizeof (eh_context) is at least + 24 bytes for x86 currently). + + This memory leak may be significant for long-running applications + that make heavy use of C++ EH. + + However, Mingw runtime (version 0.3 or newer) provides a mechanism + to emulate pthreads key dtors; the runtime provides a special DLL, + linked in if -mthreads option is specified, that runs the dtors in + the reverse order of registration when each thread exits. If + -mthreads option is not given, a stub is linked in instead of the + DLL, which results in memory leak. Other x86-win32 ports can use + the same technique of course to avoid the leak. + + 2. The error codes returned are non-POSIX like, and cast into ints. + This may cause incorrect error return due to truncation values on + hw where sizeof (DWORD) > sizeof (int). + + 3. We are currently using a special mutex instead of the Critical + Sections, since Win9x does not support TryEnterCriticalSection + (while NT does). + + The basic framework should work well enough. In the long term, GCC + needs to use Structured Exception Handling on Windows32. */ + +int +__gthr_win32_once (__gthread_once_t *once, void (*func) (void)) +{ + if (once == NULL || func == NULL) + return EINVAL; + + if (! once->done) + { + if (InterlockedIncrement (&(once->started)) == 0) + { + (*func) (); + once->done = TRUE; + } + else + { + /* Another thread is currently executing the code, so wait for it + to finish; yield the CPU in the meantime. If performance + does become an issue, the solution is to use an Event that + we wait on here (and set above), but that implies a place to + create the event before this routine is called. */ + while (! once->done) + Sleep (0); + } + } + return 0; +} + +/* Windows32 thread local keys don't support destructors; this leads to + leaks, especially in threaded applications making extensive use of + C++ EH. Mingw uses a thread-support DLL to work-around this problem. */ + +int +__gthr_win32_key_create (__gthread_key_t *key, + void (*dtor) (void *) __attribute__((unused))) +{ + int status = 0; + DWORD tls_index = TlsAlloc (); + if (tls_index != 0xFFFFFFFF) + { + *key = tls_index; +#ifdef MINGW32_SUPPORTS_MT_EH + /* Mingw runtime will run the dtors in reverse order for each thread + when the thread exits. */ + status = __mingwthr_key_dtor (*key, dtor); +#endif + } + else + status = (int) GetLastError (); + return status; +} + +int +__gthr_win32_key_delete (__gthread_key_t key) +{ + return (TlsFree (key) != 0) ? 0 : (int) GetLastError (); +} + +void * +__gthr_win32_getspecific (__gthread_key_t key) +{ + DWORD lasterror; + void *ptr; + lasterror = GetLastError(); + ptr = TlsGetValue(key); + SetLastError( lasterror ); + return ptr; +} + +int +__gthr_win32_setspecific (__gthread_key_t key, const void *ptr) +{ + if (TlsSetValue (key, CONST_CAST2(void *, const void *, ptr)) != 0) + return 0; + else + return GetLastError (); +} + +void +__gthr_win32_mutex_init_function (__gthread_mutex_t *mutex) +{ + mutex->counter = -1; + mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); +} + +void +__gthr_win32_mutex_destroy (__gthread_mutex_t *mutex) +{ + CloseHandle ((HANDLE) mutex->sema); +} + +int +__gthr_win32_mutex_lock (__gthread_mutex_t *mutex) +{ + if (InterlockedIncrement (&mutex->counter) == 0 || + WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0) + return 0; + else + { + /* WaitForSingleObject returns WAIT_FAILED, and we can only do + some best-effort cleanup here. */ + InterlockedDecrement (&mutex->counter); + return 1; + } +} + +int +__gthr_win32_mutex_trylock (__gthread_mutex_t *mutex) +{ + if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0) + return 0; + else + return 1; +} + +int +__gthr_win32_mutex_unlock (__gthread_mutex_t *mutex) +{ + if (InterlockedDecrement (&mutex->counter) >= 0) + return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1; + else + return 0; +} + +void +__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) +{ + mutex->counter = -1; + mutex->depth = 0; + mutex->owner = 0; + mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); +} + +int +__gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex) +{ + DWORD me = GetCurrentThreadId(); + if (InterlockedIncrement (&mutex->counter) == 0) + { + mutex->depth = 1; + mutex->owner = me; + } + else if (mutex->owner == me) + { + InterlockedDecrement (&mutex->counter); + ++(mutex->depth); + } + else if (WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0) + { + mutex->depth = 1; + mutex->owner = me; + } + else + { + /* WaitForSingleObject returns WAIT_FAILED, and we can only do + some best-effort cleanup here. */ + InterlockedDecrement (&mutex->counter); + return 1; + } + return 0; +} + +int +__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex) +{ + DWORD me = GetCurrentThreadId(); + if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0) + { + mutex->depth = 1; + mutex->owner = me; + } + else if (mutex->owner == me) + ++(mutex->depth); + else + return 1; + + return 0; +} + +int +__gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex) +{ + --(mutex->depth); + if (mutex->depth == 0) + { + mutex->owner = 0; + + if (InterlockedDecrement (&mutex->counter) >= 0) + return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1; + } + + return 0; +} diff --git a/libgcc/config/i386/t-cygming b/libgcc/config/i386/t-cygming index ad63bbb..d76004c 100644 --- a/libgcc/config/i386/t-cygming +++ b/libgcc/config/i386/t-cygming @@ -1,3 +1,8 @@ +# If we are building next to winsup, this will let us find the real +# limits.h when building libgcc2. Otherwise, winsup must be installed +# first. +LIBGCC2_INCLUDES = -I$(srcdir)/../winsup/w32api/include + CUSTOM_CRTSTUFF = yes crtbegin.o: $(srcdir)/config/i386/cygming-crtbegin.c diff --git a/libgcc/config/i386/t-cygwin b/libgcc/config/i386/t-cygwin index 22df636..f85ec24 100644 --- a/libgcc/config/i386/t-cygwin +++ b/libgcc/config/i386/t-cygwin @@ -1,3 +1,9 @@ +# If we are building next to winsup, this will let us find the real +# limits.h when building libgcc2. Otherwise, winsup must be installed +# first. +LIBGCC2_INCLUDES += -I$(srcdir)/../winsup/include \ + -I$(srcdir)/../winsup/cygwin/include + # Cygwin-specific parts of LIB_SPEC SHLIB_LC = -lcygwin -ladvapi32 -lshell32 -luser32 -lkernel32 diff --git a/libgcc/config/i386/t-darwin b/libgcc/config/i386/t-darwin new file mode 100644 index 0000000..5f2c697 --- /dev/null +++ b/libgcc/config/i386/t-darwin @@ -0,0 +1,3 @@ +LIB2_SIDITI_CONV_FUNCS = yes +LIB2ADD = $(srcdir)/config/darwin-64.c +LIB2FUNCS_EXCLUDE = _fixtfdi _fixunstfdi _floatditf _floatunditf diff --git a/libgcc/config/i386/t-darwin64 b/libgcc/config/i386/t-darwin64 new file mode 100644 index 0000000..30cf58b --- /dev/null +++ b/libgcc/config/i386/t-darwin64 @@ -0,0 +1,2 @@ +LIB2_SIDITI_CONV_FUNCS = yes +LIB2ADD = $(srcdir)/config/darwin-64.c diff --git a/libgcc/config/i386/t-gthr-win32 b/libgcc/config/i386/t-gthr-win32 new file mode 100644 index 0000000..e7380d6 --- /dev/null +++ b/libgcc/config/i386/t-gthr-win32 @@ -0,0 +1,2 @@ +# We hide calls to w32api needed for w32 thread support here: +LIB2ADD = $(srcdir)/config/i386/gthr-win32.c diff --git a/libgcc/config/i386/t-interix b/libgcc/config/i386/t-interix new file mode 100644 index 0000000..8889e7c --- /dev/null +++ b/libgcc/config/i386/t-interix @@ -0,0 +1,3 @@ +# We need to override LIBGCC2_DEBUG_CFLAGS so libgcc2 will be +# built without debugging information +LIBGCC2_DEBUG_CFLAGS = diff --git a/libgcc/config/i386/t-nto b/libgcc/config/i386/t-nto index 0efb5b1..44c9066 100644 --- a/libgcc/config/i386/t-nto +++ b/libgcc/config/i386/t-nto @@ -1 +1,3 @@ -CRTSTUFF_T_CFLAGS = -fno-omit-frame-pointer -fPIC +HOST_LIBGCC2_CFLAGS += -fexceptions + +CRTSTUFF_T_CFLAGS = -fno-omit-frame-pointer $(PICFLAG) diff --git a/libgcc/config/i386/t-sol2 b/libgcc/config/i386/t-sol2 index 1102146..b9cfb00 100644 --- a/libgcc/config/i386/t-sol2 +++ b/libgcc/config/i386/t-sol2 @@ -7,7 +7,7 @@ # We must also enable optimization to avoid having any code appear after # the call & alignment statement, but before we switch back to the # .text section. -CRTSTUFF_T_CFLAGS = -fPIC -O2 +CRTSTUFF_T_CFLAGS = $(PICFLAG) -O2 # Add support for the introduction of 128-bit long double. SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-sol2.ver diff --git a/libgcc/config/ia64/quadlib.c b/libgcc/config/ia64/quadlib.c new file mode 100644 index 0000000..f9ee30b --- /dev/null +++ b/libgcc/config/ia64/quadlib.c @@ -0,0 +1,78 @@ +/* Subroutines for long double support. + Copyright (C) 2000, 2001, 2002, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +extern int _U_Qfcmp (long double a, long double b, int); + +int _U_Qfeq (long double, long double); +int _U_Qfne (long double, long double); +int _U_Qfgt (long double, long double); +int _U_Qfge (long double, long double); +int _U_Qflt (long double, long double); +int _U_Qfle (long double, long double); +int _U_Qfcomp (long double, long double); + +int +_U_Qfeq (long double a, long double b) +{ + return (_U_Qfcmp (a, b, 4) != 0); +} + +int +_U_Qfne (long double a, long double b) +{ + return (_U_Qfcmp (a, b, 4) == 0); +} + +int +_U_Qfgt (long double a, long double b) +{ + return (_U_Qfcmp (a, b, 17) != 0); +} + +int +_U_Qfge (long double a, long double b) +{ + return (_U_Qfcmp (a, b, 21) != 0); +} + +int +_U_Qflt (long double a, long double b) +{ + return (_U_Qfcmp (a, b, 9) != 0); +} + +int +_U_Qfle (long double a, long double b) +{ + return (_U_Qfcmp (a, b, 13) != 0); +} + +int +_U_Qfcomp (long double a, long double b) +{ + if (_U_Qfcmp (a, b, 4) == 0) + return 0; + + return (_U_Qfcmp (a, b, 22) != 0 ? 1 : -1); +} diff --git a/libgcc/config/ia64/t-hpux b/libgcc/config/ia64/t-hpux index 1fee413..ddc1135 100644 --- a/libgcc/config/ia64/t-hpux +++ b/libgcc/config/ia64/t-hpux @@ -3,4 +3,7 @@ # to 80 bit conversions and were done for Linux backwards compatibility. LIB1ASMFUNCS := $(filter-out _fixtfdi _fixunstfdi _floatditf,$(LIB1ASMFUNCS)) +# Support routines for HP-UX 128 bit floats. +LIB2ADD = $(srcdir)/config/ia64/quadlib.c $(srcdir)/floatunsitf.c + LIB2ADDEH = $(srcdir)/unwind-c.c diff --git a/libgcc/config/ia64/t-ia64 b/libgcc/config/ia64/t-ia64 index 80445d8..93f38da 100644 --- a/libgcc/config/ia64/t-ia64 +++ b/libgcc/config/ia64/t-ia64 @@ -11,6 +11,13 @@ LIB1ASMFUNCS = __divxf3 __divdf3 __divsf3 \ __nonlocal_goto __restore_stack_nonlocal __trampoline \ _fixtfdi _fixunstfdi _floatditf +# ??? Hack to get -P option used when compiling lib1funcs.S, because Intel +# assembler does not accept # line number as a comment. +# ??? This breaks C++ pragma interface/implementation, which is used in the +# C++ part of libgcc2, hence it had to be disabled. Must find some other way +# to support the Intel assembler. +#LIBGCC2_DEBUG_CFLAGS = -g1 -P + CUSTOM_CRTSTUFF = yes # Assemble startup files. diff --git a/libgcc/config/iq2000/lib2funcs.c b/libgcc/config/iq2000/lib2funcs.c new file mode 100644 index 0000000..d53786c --- /dev/null +++ b/libgcc/config/iq2000/lib2funcs.c @@ -0,0 +1,40 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +typedef unsigned int USItype __attribute__ ((mode (SI))); + +USItype +__mulsi3 (USItype a, USItype b) +{ + USItype c = 0; + + while (a != 0) + { + if (a & 1) + c += b; + a >>= 1; + b <<= 1; + } + + return c; +} diff --git a/libgcc/config/iq2000/t-iq2000 b/libgcc/config/iq2000/t-iq2000 new file mode 100644 index 0000000..18fd53c --- /dev/null +++ b/libgcc/config/iq2000/t-iq2000 @@ -0,0 +1,5 @@ +LIB2ADD = $(srcdir)/udivmod.c \ + $(srcdir)/divmod.c \ + $(srcdir)/udivmodsi4.c \ + $(srcdir)/config/iq2000/lib2funcs.c + diff --git a/libgcc/config/lm32/t-uclinux b/libgcc/config/lm32/t-uclinux index d388f56..764243c 100644 --- a/libgcc/config/lm32/t-uclinux +++ b/libgcc/config/lm32/t-uclinux @@ -1,2 +1,2 @@ -CRTSTUFF_T_CFLAGS = -fPIC -msign-extend-enabled -HOST_LIBGCC2_CFLAGS = -fPIC -msign-extend-enabled +CRTSTUFF_T_CFLAGS = $(PICFLAG) -msign-extend-enabled +HOST_LIBGCC2_CFLAGS += -msign-extend-enabled diff --git a/libgcc/config/m32c/lib2funcs.c b/libgcc/config/m32c/lib2funcs.c new file mode 100644 index 0000000..274affc --- /dev/null +++ b/libgcc/config/m32c/lib2funcs.c @@ -0,0 +1,134 @@ +/* libgcc routines for R8C/M16C/M32C + Copyright (C) 2005, 2009 + Free Software Foundation, Inc. + Contributed by Red Hat. + + 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/>. */ + +typedef int sint32_type __attribute__ ((mode (SI))); +typedef unsigned int uint32_type __attribute__ ((mode (SI))); +typedef int word_type __attribute__ ((mode (__word__))); + +uint32_type udivmodsi4 (uint32_type, uint32_type, word_type); +sint32_type __divsi3 (sint32_type, sint32_type); +sint32_type __modsi3 (sint32_type, sint32_type); + +uint32_type +udivmodsi4 (uint32_type num, uint32_type den, word_type modwanted) +{ + uint32_type bit = 1; + uint32_type res = 0; + + while (den < num && bit && !(den & (1L << 31))) + { + den <<= 1; + bit <<= 1; + } + while (bit) + { + if (num >= den) + { + num -= den; + res |= bit; + } + bit >>= 1; + den >>= 1; + } + if (modwanted) + return num; + return res; +} + +sint32_type +__divsi3 (sint32_type a, sint32_type b) +{ + word_type neg = 0; + sint32_type res; + + if (a < 0) + { + a = -a; + neg = !neg; + } + + if (b < 0) + { + b = -b; + neg = !neg; + } + + res = udivmodsi4 (a, b, 0); + + if (neg) + res = -res; + + return res; +} + +sint32_type +__modsi3 (sint32_type a, sint32_type b) +{ + word_type neg = 0; + sint32_type res; + + if (a < 0) + { + a = -a; + neg = 1; + } + + if (b < 0) + b = -b; + + res = udivmodsi4 (a, b, 1); + + if (neg) + res = -res; + + return res; +} + +/* See the comment by the definition of LIBGCC2_UNITS_PER_WORD in + m32c.h for why we are creating extra versions of some of the + functions defined in libgcc2.c. */ + +#define LIBGCC2_UNITS_PER_WORD 2 + +#define L_clzsi2 +#define L_ctzsi2 +#define L_ffssi2 +#define L_paritysi2 +#define L_popcountsi2 + +#include "libgcc2.c" + +uint32_type +__udivsi3 (uint32_type a, uint32_type b) +{ + return udivmodsi4 (a, b, 0); +} + +uint32_type +__umoddi3 (uint32_type a, uint32_type b) +{ + return udivmodsi4 (a, b, 1); +} diff --git a/libgcc/config/m32c/t-m32c b/libgcc/config/m32c/t-m32c index d214837..dac99ec 100644 --- a/libgcc/config/m32c/t-m32c +++ b/libgcc/config/m32c/t-m32c @@ -7,3 +7,7 @@ LIB1ASMFUNCS = \ __m32c_cmpsi2 \ __m32c_ucmpsi2 \ __m32c_jsri16 + +LIB2ADD = $(srcdir)/config/m32c/lib2funcs.c \ + $(srcdir)/config/m32c/trapv.c + diff --git a/libgcc/config/m32c/trapv.c b/libgcc/config/m32c/trapv.c new file mode 100644 index 0000000..0c8c174 --- /dev/null +++ b/libgcc/config/m32c/trapv.c @@ -0,0 +1,43 @@ +/* 16-bit trapping arithmetic routines for R8C/M16C/M32C + Copyright (C) 2009, 2011 + Free Software Foundation, Inc. + Contributed by Red Hat. + + 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/>. */ + +/* See the comment by the definition of LIBGCC2_UNITS_PER_WORD in + m32c.h for why we are creating extra versions of some of the + functions defined in libgcc2.c. + + Note - this file is separate from lib2funcs.c so that the following + functions will appear in the their object file. This is necessary + because they call abort() which is defined in the C library whereas + the functions in lib2funcs.c are completely self sufficient. */ + +#define LIBGCC2_UNITS_PER_WORD 2 + +#define L_mulvsi3 +#define L_negvsi2 +#define L_addvsi3 +#define L_subvsi3 + +#include "libgcc2.c" diff --git a/libgcc/config/m32r/t-linux b/libgcc/config/m32r/t-linux index 29c83c5..5223b73 100644 --- a/libgcc/config/m32r/t-linux +++ b/libgcc/config/m32r/t-linux @@ -1 +1,5 @@ +# Turn off the SDA while compiling libgcc2. There are no headers for it +# and we want maximal upward compatibility here. +HOST_LIBGCC2_CFLAGS += -G 0 + SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/m32r/libgcc-glibc.ver diff --git a/libgcc/config/m32r/t-m32r b/libgcc/config/m32r/t-m32r index acc0758..f32cbbe 100644 --- a/libgcc/config/m32r/t-m32r +++ b/libgcc/config/m32r/t-m32r @@ -1,3 +1,7 @@ +# Turn off the SDA while compiling libgcc2. There are no headers for it +# and we want maximal upward compatibility here. +HOST_LIBGCC2_CFLAGS = -G 0 + # We need to use -fpic when we are using gcc to compile the routines in # initfini.c. This is only really needed when we are going to use gcc/g++ # to produce a shared library, but since we don't know ahead of time when diff --git a/libgcc/config/m68k/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c new file mode 100644 index 0000000..fe41edf --- /dev/null +++ b/libgcc/config/m68k/fpgnulib.c @@ -0,0 +1,595 @@ +/* This is a stripped down version of floatlib.c. It supplies only those + functions which exist in libgcc, but for which there is not assembly + language versions in m68k/lb1sf68.S. + + It also includes simplistic support for extended floats (by working in + double precision). You must compile this file again with -DEXTFLOAT + to get this support. */ + +/* +** gnulib support for software floating point. +** Copyright (C) 1991 by Pipeline Associates, Inc. All rights reserved. +** Permission is granted to do *anything* you want with this file, +** commercial or otherwise, provided this message remains intact. So there! +** I would appreciate receiving any updates/patches/changes that anyone +** makes, and am willing to be the repository for said changes (am I +** making a big mistake?). +** +** Pat Wood +** Pipeline Associates, Inc. +** pipeline!phw@motown.com or +** sun!pipeline!phw or +** uunet!motown!pipeline!phw +** +** 05/01/91 -- V1.0 -- first release to gcc mailing lists +** 05/04/91 -- V1.1 -- added float and double prototypes and return values +** -- fixed problems with adding and subtracting zero +** -- fixed rounding in truncdfsf2 +** -- fixed SWAP define and tested on 386 +*/ + +/* +** The following are routines that replace the gnulib soft floating point +** routines that are called automatically when -msoft-float is selected. +** The support single and double precision IEEE format, with provisions +** for byte-swapped machines (tested on 386). Some of the double-precision +** routines work at full precision, but most of the hard ones simply punt +** and call the single precision routines, producing a loss of accuracy. +** long long support is not assumed or included. +** Overall accuracy is close to IEEE (actually 68882) for single-precision +** arithmetic. I think there may still be a 1 in 1000 chance of a bit +** being rounded the wrong way during a multiply. I'm not fussy enough to +** bother with it, but if anyone is, knock yourself out. +** +** Efficiency has only been addressed where it was obvious that something +** would make a big difference. Anyone who wants to do this right for +** best speed should go in and rewrite in assembler. +** +** I have tested this only on a 68030 workstation and 386/ix integrated +** in with -msoft-float. +*/ + +/* the following deal with IEEE single-precision numbers */ +#define EXCESS 126L +#define SIGNBIT 0x80000000L +#define HIDDEN (1L << 23L) +#define SIGN(fp) ((fp) & SIGNBIT) +#define EXP(fp) (((fp) >> 23L) & 0xFF) +#define MANT(fp) (((fp) & 0x7FFFFFL) | HIDDEN) +#define PACK(s,e,m) ((s) | ((e) << 23L) | (m)) + +/* the following deal with IEEE double-precision numbers */ +#define EXCESSD 1022L +#define HIDDEND (1L << 20L) +#define EXPDBITS 11 +#define EXPDMASK 0x7FFL +#define EXPD(fp) (((fp.l.upper) >> 20L) & 0x7FFL) +#define SIGND(fp) ((fp.l.upper) & SIGNBIT) +#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \ + (fp.l.lower >> 22)) +#define MANTDMASK 0xFFFFFL /* mask of upper part */ + +/* the following deal with IEEE extended-precision numbers */ +#define EXCESSX 16382L +#define HIDDENX (1L << 31L) +#define EXPXBITS 15 +#define EXPXMASK 0x7FFF +#define EXPX(fp) (((fp.l.upper) >> 16) & EXPXMASK) +#define SIGNX(fp) ((fp.l.upper) & SIGNBIT) +#define MANTXMASK 0x7FFFFFFFL /* mask of upper part */ + +union double_long +{ + double d; + struct { + long upper; + unsigned long lower; + } l; +}; + +union float_long { + float f; + long l; +}; + +union long_double_long +{ + long double ld; + struct + { + long upper; + unsigned long middle; + unsigned long lower; + } l; +}; + +#ifndef EXTFLOAT + +int +__unordsf2(float a, float b) +{ + union float_long fl; + + fl.f = a; + if (EXP(fl.l) == EXP(~0u) && (MANT(fl.l) & ~HIDDEN) != 0) + return 1; + fl.f = b; + if (EXP(fl.l) == EXP(~0u) && (MANT(fl.l) & ~HIDDEN) != 0) + return 1; + return 0; +} + +int +__unorddf2(double a, double b) +{ + union double_long dl; + + dl.d = a; + if (EXPD(dl) == EXPDMASK + && ((dl.l.upper & MANTDMASK) != 0 || dl.l.lower != 0)) + return 1; + dl.d = b; + if (EXPD(dl) == EXPDMASK + && ((dl.l.upper & MANTDMASK) != 0 || dl.l.lower != 0)) + return 1; + return 0; +} + +/* convert unsigned int to double */ +double +__floatunsidf (unsigned long a1) +{ + long exp = 32 + EXCESSD; + union double_long dl; + + if (!a1) + { + dl.l.upper = dl.l.lower = 0; + return dl.d; + } + + while (a1 < 0x2000000L) + { + a1 <<= 4; + exp -= 4; + } + + while (a1 < 0x80000000L) + { + a1 <<= 1; + exp--; + } + + /* pack up and go home */ + dl.l.upper = exp << 20L; + dl.l.upper |= (a1 >> 11L) & ~HIDDEND; + dl.l.lower = a1 << 21L; + + return dl.d; +} + +/* convert int to double */ +double +__floatsidf (long a1) +{ + long sign = 0, exp = 31 + EXCESSD; + union double_long dl; + + if (!a1) + { + dl.l.upper = dl.l.lower = 0; + return dl.d; + } + + if (a1 < 0) + { + sign = SIGNBIT; + a1 = (long)-(unsigned long)a1; + if (a1 < 0) + { + dl.l.upper = SIGNBIT | ((32 + EXCESSD) << 20L); + dl.l.lower = 0; + return dl.d; + } + } + + while (a1 < 0x1000000L) + { + a1 <<= 4; + exp -= 4; + } + + while (a1 < 0x40000000L) + { + a1 <<= 1; + exp--; + } + + /* pack up and go home */ + dl.l.upper = sign; + dl.l.upper |= exp << 20L; + dl.l.upper |= (a1 >> 10L) & ~HIDDEND; + dl.l.lower = a1 << 22L; + + return dl.d; +} + +/* convert unsigned int to float */ +float +__floatunsisf (unsigned long l) +{ + double foo = __floatunsidf (l); + return foo; +} + +/* convert int to float */ +float +__floatsisf (long l) +{ + double foo = __floatsidf (l); + return foo; +} + +/* convert float to double */ +double +__extendsfdf2 (float a1) +{ + register union float_long fl1; + register union double_long dl; + register long exp; + register long mant; + + fl1.f = a1; + + dl.l.upper = SIGN (fl1.l); + if ((fl1.l & ~SIGNBIT) == 0) + { + dl.l.lower = 0; + return dl.d; + } + + exp = EXP(fl1.l); + mant = MANT (fl1.l) & ~HIDDEN; + if (exp == 0) + { + /* Denormal. */ + exp = 1; + while (!(mant & HIDDEN)) + { + mant <<= 1; + exp--; + } + mant &= ~HIDDEN; + } + exp = exp - EXCESS + EXCESSD; + dl.l.upper |= exp << 20; + dl.l.upper |= mant >> 3; + dl.l.lower = mant << 29; + + return dl.d; +} + +/* convert double to float */ +float +__truncdfsf2 (double a1) +{ + register long exp; + register long mant; + register union float_long fl; + register union double_long dl1; + int sticky; + int shift; + + dl1.d = a1; + + if ((dl1.l.upper & ~SIGNBIT) == 0 && !dl1.l.lower) + { + fl.l = SIGND(dl1); + return fl.f; + } + + exp = EXPD (dl1) - EXCESSD + EXCESS; + + sticky = dl1.l.lower & ((1 << 22) - 1); + mant = MANTD (dl1); + /* shift double mantissa 6 bits so we can round */ + sticky |= mant & ((1 << 6) - 1); + mant >>= 6; + + /* Check for underflow and denormals. */ + if (exp <= 0) + { + if (exp < -24) + { + sticky |= mant; + mant = 0; + } + else + { + sticky |= mant & ((1 << (1 - exp)) - 1); + mant >>= 1 - exp; + } + exp = 0; + } + + /* now round */ + shift = 1; + if ((mant & 1) && (sticky || (mant & 2))) + { + int rounding = exp ? 2 : 1; + + mant += 1; + + /* did the round overflow? */ + if (mant >= (HIDDEN << rounding)) + { + exp++; + shift = rounding; + } + } + /* shift down */ + mant >>= shift; + + mant &= ~HIDDEN; + + /* pack up and go home */ + fl.l = PACK (SIGND (dl1), exp, mant); + return (fl.f); +} + +/* convert double to int */ +long +__fixdfsi (double a1) +{ + register union double_long dl1; + register long exp; + register long l; + + dl1.d = a1; + + if (!dl1.l.upper && !dl1.l.lower) + return 0; + + exp = EXPD (dl1) - EXCESSD - 31; + l = MANTD (dl1); + + if (exp > 0) + { + /* Return largest integer. */ + return SIGND (dl1) ? 0x80000000L : 0x7fffffffL; + } + + if (exp <= -32) + return 0; + + /* shift down until exp = 0 */ + if (exp < 0) + l >>= -exp; + + return (SIGND (dl1) ? -l : l); +} + +/* convert float to int */ +long +__fixsfsi (float a1) +{ + double foo = a1; + return __fixdfsi (foo); +} + +#else /* EXTFLOAT */ + +/* We do not need these routines for coldfire, as it has no extended + float format. */ +#if !defined (__mcoldfire__) + +/* Primitive extended precision floating point support. + + We assume all numbers are normalized, don't do any rounding, etc. */ + +/* Prototypes for the above in case we use them. */ +double __floatunsidf (unsigned long); +double __floatsidf (long); +float __floatsisf (long); +double __extendsfdf2 (float); +float __truncdfsf2 (double); +long __fixdfsi (double); +long __fixsfsi (float); + +int +__unordxf2(long double a, long double b) +{ + union long_double_long ldl; + + ldl.ld = a; + if (EXPX(ldl) == EXPXMASK + && ((ldl.l.middle & MANTXMASK) != 0 || ldl.l.lower != 0)) + return 1; + ldl.ld = b; + if (EXPX(ldl) == EXPXMASK + && ((ldl.l.middle & MANTXMASK) != 0 || ldl.l.lower != 0)) + return 1; + return 0; +} + +/* convert double to long double */ +long double +__extenddfxf2 (double d) +{ + register union double_long dl; + register union long_double_long ldl; + register long exp; + + dl.d = d; + /*printf ("dfxf in: %g\n", d);*/ + + ldl.l.upper = SIGND (dl); + if ((dl.l.upper & ~SIGNBIT) == 0 && !dl.l.lower) + { + ldl.l.middle = 0; + ldl.l.lower = 0; + return ldl.ld; + } + + exp = EXPD (dl) - EXCESSD + EXCESSX; + ldl.l.upper |= exp << 16; + ldl.l.middle = HIDDENX; + /* 31-20: # mantissa bits in ldl.l.middle - # mantissa bits in dl.l.upper */ + ldl.l.middle |= (dl.l.upper & MANTDMASK) << (31 - 20); + /* 1+20: explicit-integer-bit + # mantissa bits in dl.l.upper */ + ldl.l.middle |= dl.l.lower >> (1 + 20); + /* 32 - 21: # bits of dl.l.lower in ldl.l.middle */ + ldl.l.lower = dl.l.lower << (32 - 21); + + /*printf ("dfxf out: %s\n", dumpxf (ldl.ld));*/ + return ldl.ld; +} + +/* convert long double to double */ +double +__truncxfdf2 (long double ld) +{ + register long exp; + register union double_long dl; + register union long_double_long ldl; + + ldl.ld = ld; + /*printf ("xfdf in: %s\n", dumpxf (ld));*/ + + dl.l.upper = SIGNX (ldl); + if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle && !ldl.l.lower) + { + dl.l.lower = 0; + return dl.d; + } + + exp = EXPX (ldl) - EXCESSX + EXCESSD; + /* ??? quick and dirty: keep `exp' sane */ + if (exp >= EXPDMASK) + exp = EXPDMASK - 1; + dl.l.upper |= exp << (32 - (EXPDBITS + 1)); + /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */ + dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1); + dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1)); + dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1); + + /*printf ("xfdf out: %g\n", dl.d);*/ + return dl.d; +} + +/* convert a float to a long double */ +long double +__extendsfxf2 (float f) +{ + long double foo = __extenddfxf2 (__extendsfdf2 (f)); + return foo; +} + +/* convert a long double to a float */ +float +__truncxfsf2 (long double ld) +{ + float foo = __truncdfsf2 (__truncxfdf2 (ld)); + return foo; +} + +/* convert an int to a long double */ +long double +__floatsixf (long l) +{ + double foo = __floatsidf (l); + return foo; +} + +/* convert an unsigned int to a long double */ +long double +__floatunsixf (unsigned long l) +{ + double foo = __floatunsidf (l); + return foo; +} + +/* convert a long double to an int */ +long +__fixxfsi (long double ld) +{ + long foo = __fixdfsi ((double) ld); + return foo; +} + +/* The remaining provide crude math support by working in double precision. */ + +long double +__addxf3 (long double x1, long double x2) +{ + return (double) x1 + (double) x2; +} + +long double +__subxf3 (long double x1, long double x2) +{ + return (double) x1 - (double) x2; +} + +long double +__mulxf3 (long double x1, long double x2) +{ + return (double) x1 * (double) x2; +} + +long double +__divxf3 (long double x1, long double x2) +{ + return (double) x1 / (double) x2; +} + +long double +__negxf2 (long double x1) +{ + return - (double) x1; +} + +long +__cmpxf2 (long double x1, long double x2) +{ + return __cmpdf2 ((double) x1, (double) x2); +} + +long +__eqxf2 (long double x1, long double x2) +{ + return __cmpdf2 ((double) x1, (double) x2); +} + +long +__nexf2 (long double x1, long double x2) +{ + return __cmpdf2 ((double) x1, (double) x2); +} + +long +__ltxf2 (long double x1, long double x2) +{ + return __cmpdf2 ((double) x1, (double) x2); +} + +long +__lexf2 (long double x1, long double x2) +{ + return __cmpdf2 ((double) x1, (double) x2); +} + +long +__gtxf2 (long double x1, long double x2) +{ + return __cmpdf2 ((double) x1, (double) x2); +} + +long +__gexf2 (long double x1, long double x2) +{ + return __cmpdf2 ((double) x1, (double) x2); +} + +#endif /* !__mcoldfire__ */ +#endif /* EXTFLOAT */ diff --git a/libgcc/config/m68k/t-floatlib b/libgcc/config/m68k/t-floatlib index 4160eb9..1ee8782 100644 --- a/libgcc/config/m68k/t-floatlib +++ b/libgcc/config/m68k/t-floatlib @@ -3,3 +3,9 @@ LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \ _double _float _floatex \ _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \ _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2 + +LIB2ADD = $(srcdir)/config/m68k/fpgnulib.c xfgnulib.c + +xfgnulib.c: $(srcdir)/config/m68k/fpgnulib.c + echo '#define EXTFLOAT' > xfgnulib.c + cat $< >> xfgnulib.c diff --git a/libgcc/config/mcore/t-mcore b/libgcc/config/mcore/t-mcore index 19c4c15..fe024c7 100644 --- a/libgcc/config/mcore/t-mcore +++ b/libgcc/config/mcore/t-mcore @@ -1,2 +1,5 @@ LIB1ASMSRC = mcore/lib1funcs.S LIB1ASMFUNCS = _divsi3 _udivsi3 _modsi3 _umodsi3 + +# could use -msifilter to be safe from interrupt/jmp interactions and others. +HOST_LIBGCC2_CFLAGS = -O3 -DNO_FLOATLIB_FIXUNSDFSI #-msifilter diff --git a/libgcc/config/mep/lib2funcs.c b/libgcc/config/mep/lib2funcs.c new file mode 100644 index 0000000..1dbf57d --- /dev/null +++ b/libgcc/config/mep/lib2funcs.c @@ -0,0 +1,139 @@ +/* libgcc routines for MeP. + Copyright 2001, 2002, 2009 Free Software Foundation, Inc + +This file 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 of the License, or (at your +option) any later version. + +This file 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/>. */ + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); + +typedef int word_type __attribute__ ((mode (__word__))); + +USItype +__mulsi3 (USItype a, USItype b) +{ + USItype c = 0; + + while (a != 0) + { + if (a & 1) + c += b; + a >>= 1; + b <<= 1; + } + + return c; +} + + + +USItype +udivmodsi4(USItype num, USItype den, word_type modwanted) +{ + USItype bit = 1; + USItype res = 0; + + while (den < num && bit && !(den & (1L<<31))) + { + den <<=1; + bit <<=1; + } + while (bit) + { + if (num >= den) + { + num -= den; + res |= bit; + } + bit >>=1; + den >>=1; + } + if (modwanted) return num; + return res; +} + + + +SItype +__divsi3 (SItype a, SItype b) +{ + word_type neg = 0; + SItype res; + + if (a < 0) + { + a = -a; + neg = !neg; + } + + if (b < 0) + { + b = -b; + neg = !neg; + } + + res = udivmodsi4 (a, b, 0); + + if (neg) + res = -res; + + return res; +} + + + +SItype +__modsi3 (SItype a, SItype b) +{ + word_type neg = 0; + SItype res; + + if (a < 0) + { + a = -a; + neg = 1; + } + + if (b < 0) + b = -b; + + res = udivmodsi4 (a, b, 1); + + if (neg) + res = -res; + + return res; +} + + + + +SItype +__udivsi3 (SItype a, SItype b) +{ + return udivmodsi4 (a, b, 0); +} + + + +SItype +__umodsi3 (SItype a, SItype b) +{ + return udivmodsi4 (a, b, 1); +} diff --git a/libgcc/config/mep/t-mep b/libgcc/config/mep/t-mep index d1fb094..fb3a0d6 100644 --- a/libgcc/config/mep/t-mep +++ b/libgcc/config/mep/t-mep @@ -7,5 +7,10 @@ LIB1ASMFUNCS = _mep_profile \ _mep_bb_trace \ _mep_bb_increment +# multiply and divide routines +LIB2ADD = \ + $(srcdir)/config/mep/lib2funcs.c \ + $(srcdir)/config/mep/tramp.c + # Use -O0 instead of -O2 so we don't get complex relocations CRTSTUFF_CFLAGS += -O0 diff --git a/libgcc/config/mep/tramp.c b/libgcc/config/mep/tramp.c new file mode 100644 index 0000000..bf484ca --- /dev/null +++ b/libgcc/config/mep/tramp.c @@ -0,0 +1,103 @@ +/* Trampoline support for MeP + Copyright (C) 2004, 2007 Free Software Foundation, Inc. + Contributed by Red Hat Inc. + +This file 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 of the License, or (at your +option) any later version. + +This file 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/>. */ + +/* + 7a0a ldc $10,$pc + c0ae000a lw $0,10($10) + caae000e lw $10,14($10) + 10ae jmp $10 + 00000000 static chain + 00000000 function address +*/ + +static inline int +cache_config_register(void) { + int rv; + asm ("ldc\t%0, $ccfg" : "=r" (rv)); + return rv; +} + +#define ICACHE_SIZE ((cache_config_register() >> 16) & 0x7f) +#define DCACHE_SIZE (cache_config_register() & 0x7f) + +#define ICACHE_DATA_BASE 0x00300000 +#define ICACHE_TAG_BASE 0x00310000 +#define DCACHE_DATA_BASE 0x00320000 +#define DCACHE_TAG_BASE 0x00330000 + +static inline void +flush_dcache (int addr) +{ + asm volatile ("cache\t0, (%0)" : : "r" (addr)); +} + +void +__mep_trampoline_helper (unsigned long *tramp, + int function_address, + int static_chain); + +void +__mep_trampoline_helper (unsigned long *tramp, + int function_address, + int static_chain) +{ + int dsize, isize; + +#ifdef __LITTLE_ENDIAN__ + tramp[0] = 0xc0ae7a0a; + tramp[1] = 0xcaae000a; + tramp[2] = 0x10ae000e; +#else + tramp[0] = 0x7a0ac0ae; + tramp[1] = 0x000acaae; + tramp[2] = 0x000e10ae; +#endif + tramp[3] = static_chain; + tramp[4] = function_address; + + dsize = DCACHE_SIZE; + isize = ICACHE_SIZE; + + if (dsize) + { + flush_dcache ((int)tramp); + flush_dcache ((int)tramp+16); + } + + if (isize) + { + int imask = (isize * 1024) - 1; + int tmask = ~imask; + unsigned int i; + volatile unsigned int *tags; + + imask &= 0xffe0; + + for (i=(unsigned int)tramp; i<(unsigned int)tramp+20; i+=16) + { + tags = (unsigned int *)(ICACHE_TAG_BASE + (i & imask)); + if ((*tags & tmask) == (i & tmask)) + *tags &= ~1; + } + } +} diff --git a/libgcc/config/microblaze/divsi3.asm b/libgcc/config/microblaze/divsi3.S index 7d888b3..f3b7a19 100644 --- a/libgcc/config/microblaze/divsi3.asm +++ b/libgcc/config/microblaze/divsi3.S @@ -1,6 +1,6 @@ ###################################- # -# Copyright 2009, 2010 Free Software Foundation, Inc. +# Copyright 2009, 2010, 2011 Free Software Foundation, Inc. # # Contributed by Michael Eager <eager@eagercon.com>. # @@ -23,7 +23,7 @@ # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # <http://www.gnu.org/licenses/>. # -# divsi3.asm +# divsi3.S # # Divide operation for 32 bit integers. # Input : Dividend in Reg r5 diff --git a/libgcc/config/microblaze/moddi3.asm b/libgcc/config/microblaze/moddi3.S index 4923b45..3e8d94f 100644 --- a/libgcc/config/microblaze/moddi3.asm +++ b/libgcc/config/microblaze/moddi3.S @@ -1,6 +1,6 @@ ################################### # -# Copyright 2009, 2010 Free Software Foundation, Inc. +# Copyright 2009, 2010, 2011 Free Software Foundation, Inc. # # Contributed by Michael Eager <eager@eagercon.com>. # @@ -23,7 +23,7 @@ # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # <http://www.gnu.org/licenses/>. # -# modsi3.asm +# modsi3.S # # modulo operation for 64 bit integers. # diff --git a/libgcc/config/microblaze/modsi3.asm b/libgcc/config/microblaze/modsi3.S index cae95c8..4be6be4 100644 --- a/libgcc/config/microblaze/modsi3.asm +++ b/libgcc/config/microblaze/modsi3.S @@ -1,6 +1,6 @@ ################################### # -# Copyright 2009, 2010 Free Software Foundation, Inc. +# Copyright 2009, 2010, 2011 Free Software Foundation, Inc. # # Contributed by Michael Eager <eager@eagercon.com>. # @@ -23,7 +23,7 @@ # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # <http://www.gnu.org/licenses/>. # -# modsi3.asm +# modsi3.S # # modulo operation for 32 bit integers. # Input : op1 in Reg r5 diff --git a/libgcc/config/microblaze/muldi3_hard.asm b/libgcc/config/microblaze/muldi3_hard.S index 0499e2a..14cfff5 100644 --- a/libgcc/config/microblaze/muldi3_hard.asm +++ b/libgcc/config/microblaze/muldi3_hard.S @@ -1,6 +1,6 @@ ###################################- # -# Copyright 2009, 2010 Free Software Foundation, Inc. +# Copyright 2009, 2010, 2011 Free Software Foundation, Inc. # # Contributed by Michael Eager <eager@eagercon.com>. # @@ -23,7 +23,7 @@ # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # <http://www.gnu.org/licenses/>. # -# muldi3_hard.asm +# muldi3_hard.S # # Multiply operation for 64 bit integers, for devices with hard multiply # Input : Operand1[H] in Reg r5 diff --git a/libgcc/config/microblaze/mulsi3.asm b/libgcc/config/microblaze/mulsi3.S index 03fe028..77d2daa 100644 --- a/libgcc/config/microblaze/mulsi3.asm +++ b/libgcc/config/microblaze/mulsi3.S @@ -1,6 +1,6 @@ ###################################-*-asm*- # -# Copyright 2009, 2010 Free Software Foundation, Inc. +# Copyright 2009, 2010, 2011 Free Software Foundation, Inc. # # Contributed by Michael Eager <eager@eagercon.com>. # @@ -23,7 +23,7 @@ # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # <http://www.gnu.org/licenses/>. # -# mulsi3.asm +# mulsi3.S # # Multiply operation for 32 bit integers. # Input : Operand1 in Reg r5 diff --git a/libgcc/config/microblaze/stack_overflow_exit.asm b/libgcc/config/microblaze/stack_overflow_exit.S index 30b31f0..98182a2 100644 --- a/libgcc/config/microblaze/stack_overflow_exit.asm +++ b/libgcc/config/microblaze/stack_overflow_exit.S @@ -1,6 +1,6 @@ ###################################-*-asm*- # -# Copyright 2009 Free Software Foundation, Inc. +# Copyright 2009, 2011 Free Software Foundation, Inc. # # # Contributed by Michael Eager <eager@eagercon.com>. @@ -24,7 +24,7 @@ # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # <http://www.gnu.org/licenses/>. # -# stack_overflow_exit.asm +# stack_overflow_exit.S # # Checks for stack overflows and sets the global variable # stack_overflow_error with the value of current stack pointer diff --git a/libgcc/config/microblaze/t-microblaze b/libgcc/config/microblaze/t-microblaze index ec17bb8..3a9c7ff 100644 --- a/libgcc/config/microblaze/t-microblaze +++ b/libgcc/config/microblaze/t-microblaze @@ -1,10 +1,10 @@ LIB2ADD += \ - $(srcdir)/config/microblaze/divsi3.asm \ - $(srcdir)/config/microblaze/moddi3.asm \ - $(srcdir)/config/microblaze/modsi3.asm \ - $(srcdir)/config/microblaze/muldi3_hard.asm \ - $(srcdir)/config/microblaze/mulsi3.asm \ - $(srcdir)/config/microblaze/stack_overflow_exit.asm \ - $(srcdir)/config/microblaze/udivsi3.asm \ - $(srcdir)/config/microblaze/umodsi3.asm \ + $(srcdir)/config/microblaze/divsi3.S \ + $(srcdir)/config/microblaze/moddi3.S \ + $(srcdir)/config/microblaze/modsi3.S \ + $(srcdir)/config/microblaze/muldi3_hard.S \ + $(srcdir)/config/microblaze/mulsi3.S \ + $(srcdir)/config/microblaze/stack_overflow_exit.S \ + $(srcdir)/config/microblaze/udivsi3.S \ + $(srcdir)/config/microblaze/umodsi3.S \ $(srcdir)/config/microblaze/divsi3_table.c diff --git a/libgcc/config/microblaze/udivsi3.asm b/libgcc/config/microblaze/udivsi3.S index 879cd34..07a2d65 100644 --- a/libgcc/config/microblaze/udivsi3.asm +++ b/libgcc/config/microblaze/udivsi3.S @@ -1,6 +1,6 @@ ###################################- # -# Copyright 2009, 2010 Free Software Foundation, Inc. +# Copyright 2009, 2010, 2011 Free Software Foundation, Inc. # # Contributed by Michael Eager <eager@eagercon.com>. # @@ -23,7 +23,7 @@ # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # <http://www.gnu.org/licenses/>. # -# udivsi3.asm +# udivsi3.S # # Unsigned divide operation. # Input : Divisor in Reg r5 diff --git a/libgcc/config/microblaze/umodsi3.asm b/libgcc/config/microblaze/umodsi3.S index f7fd008..67de12c 100644 --- a/libgcc/config/microblaze/umodsi3.asm +++ b/libgcc/config/microblaze/umodsi3.S @@ -1,6 +1,6 @@ ################################### # -# Copyright 2009, 2010 Free Software Foundation, Inc. +# Copyright 2009, 2010, 2011 Free Software Foundation, Inc. # # Contributed by Michael Eager <eager@eagercon.com>. # @@ -23,7 +23,7 @@ # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # <http://www.gnu.org/licenses/>. # -# umodsi3.asm +# umodsi3.S # # Unsigned modulo operation for 32 bit integers. # Input : op1 in Reg r5 diff --git a/libgcc/config/mips/t-elf b/libgcc/config/mips/t-elf new file mode 100644 index 0000000..3a1dfd7 --- /dev/null +++ b/libgcc/config/mips/t-elf @@ -0,0 +1,3 @@ +# We must build libgcc2.a with -G 0, in case the user wants to link +# without the $gp register. +HOST_LIBGCC2_CFLAGS = -G 0 diff --git a/libgcc/config/mips/t-mips b/libgcc/config/mips/t-mips index b7d13b3..719c062e 100644 --- a/libgcc/config/mips/t-mips +++ b/libgcc/config/mips/t-mips @@ -1,3 +1,5 @@ +LIB2_SIDITI_CONV_FUNCS = yes + FPBIT = true FPBIT_CFLAGS = -DQUIET_NAN_NEGATED DPBIT = true diff --git a/libgcc/config/mips/t-vr b/libgcc/config/mips/t-vr new file mode 100644 index 0000000..601fbde --- /dev/null +++ b/libgcc/config/mips/t-vr @@ -0,0 +1,2 @@ +LIB2ADD_ST = $(srcdir)/config/mips/mips16.S \ + $(srcdir)/config/mips/vr4120-div.S diff --git a/libgcc/config/mips/vr4120-div.S b/libgcc/config/mips/vr4120-div.S new file mode 100644 index 0000000..79ede3d --- /dev/null +++ b/libgcc/config/mips/vr4120-div.S @@ -0,0 +1,74 @@ +/* Support file for -mfix-vr4120. + Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +/* This file contains functions which implement divsi3 and modsi3 for + -mfix-vr4120. div and ddiv do not give the correct result when one + of the operands is negative. */ + + .set nomips16 + +#define DIV \ + xor $3,$4,$5 /* t = x ^ y */ ; \ + li $2,0x80000000; \ + .set noreorder; \ + bgez $4,1f /* x >= 0 */; \ + and $3,$3,$2 /* t = (x ^ y) & 0x80000000 in delay slot */ ;\ + .set reorder; \ + subu $4,$0,$4 /* x = -x */ ; \ +1:; \ + .set noreorder; \ + bgez $5,2f /* y >= 0 */ ; \ + nop; \ + subu $5,$0,$5 /* y = -y */ ; \ + .set reorder; \ +2:; \ + divu $0,$4,$5; /* we use divu because of INT_MIN */ \ + .set noreorder; \ + bne $5,$0,3f; \ + nop; \ + break 7 /* division on zero y */ ; \ +3:; \ + .set reorder; \ + mflo $2 /* r = x / y */ ; \ + .set noreorder; \ + beq $3,$0,4f /* t == 0 */ ; \ + nop; \ + subu $2,$0,$2 /* r = -r */ ; \ + .set reorder; \ +4: + + .globl __vr4120_divsi3 + .ent __vr4120_divsi3 +__vr4120_divsi3: + DIV + j $31 + .end __vr4120_divsi3 + + .globl __vr4120_modsi3 + .ent __vr4120_modsi3 +__vr4120_modsi3: + move $6,$4 # x1 = x + move $7,$5 # y1 = y + DIV + mult $2,$7 # r = r * y1 + mflo $2 + .set noreorder + j $31 + subu $2,$6,$2 # r = x1 - r in delay slot + .end __vr4120_modsi3 diff --git a/libgcc/config/mmix/t-mmix b/libgcc/config/mmix/t-mmix index 6793b3c..40ee1e4 100644 --- a/libgcc/config/mmix/t-mmix +++ b/libgcc/config/mmix/t-mmix @@ -1,3 +1,5 @@ +HOST_LIBGCC2_CFLAGS = -mlibfuncs -O2 + # We need to turn off some assumptions on normality for code in crtstuff.c # and crt{i,n}.S, specifically about execution not continuing past the # end of the section in the file being compiled. Thus we must stop the diff --git a/libgcc/config/pa/fptr.c b/libgcc/config/pa/fptr.c new file mode 100644 index 0000000..320d182 --- /dev/null +++ b/libgcc/config/pa/fptr.c @@ -0,0 +1,131 @@ +/* Subroutine for function pointer canonicalization on PA-RISC with ELF32. + Copyright 2002, 2003, 2004, 2007, 2009 Free Software Foundation, Inc. + Contributed by John David Anglin (dave.anglin@nrc.ca). + +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/>. */ + + +/* WARNING: The code is this function depends on internal and undocumented + details of the GNU linker and dynamic loader as implemented for parisc + linux. */ + +/* This MUST match the defines sysdeps/hppa/dl-machine.h and + bfd/elf32-hppa.c. */ +#define GOT_FROM_PLT_STUB (4*4) + +/* List of byte offsets in _dl_runtime_resolve to search for "bl" branches. + The first "bl" branch instruction found MUST be a call to fixup. See + the define for TRAMPOLINE_TEMPLATE in sysdeps/hppa/dl-machine.h. If + the trampoline template is changed, the list must be appropriately + updated. The offset of -4 allows for a magic branch at the start of + the template should it be necessary to change the current branch + position. */ +#define NOFFSETS 2 +static int fixup_branch_offset[NOFFSETS] = { 32, -4 }; + +#define GET_FIELD(X, FROM, TO) \ + ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1)) +#define SIGN_EXTEND(VAL,BITS) \ + ((int) ((VAL) >> ((BITS) - 1) ? (-1 << (BITS)) | (VAL) : (VAL))) + +struct link_map; +typedef int (*fptr_t) (void); +typedef int (*fixup_t) (struct link_map *, unsigned int); +extern unsigned int _GLOBAL_OFFSET_TABLE_; + +/* __canonicalize_funcptr_for_compare must be hidden so that it is not + placed in the dynamic symbol table. Like millicode functions, it + must be linked into all binaries in order access the got table of + that binary. However, we don't use the millicode calling convention + and the routine must be a normal function so that it can be compiled + as pic code. */ +unsigned int __canonicalize_funcptr_for_compare (fptr_t) + __attribute__ ((visibility ("hidden"))); + +unsigned int +__canonicalize_funcptr_for_compare (fptr_t fptr) +{ + static unsigned int fixup_plabel[2]; + static fixup_t fixup; + unsigned int *plabel, *got; + + /* -1 and page 0 are special. -1 is used in crtend to mark the end of + a list of function pointers. Also return immediately if the plabel + bit is not set in the function pointer. In this case, the function + pointer points directly to the function. */ + if ((int) fptr == -1 || (unsigned int) fptr < 4096 || !((int) fptr & 2)) + return (unsigned int) fptr; + + /* The function pointer points to a function descriptor (plabel). If + the plabel hasn't been resolved, the first word of the plabel points + to the entry of the PLT stub just before the global offset table. + The second word in the plabel contains the relocation offset for the + function. */ + plabel = (unsigned int *) ((unsigned int) fptr & ~3); + got = (unsigned int *) (plabel[0] + GOT_FROM_PLT_STUB); + + /* Return the address of the function if the plabel has been resolved. */ + if (got != &_GLOBAL_OFFSET_TABLE_) + return plabel[0]; + + /* Initialize our plabel for calling fixup if we haven't done so already. + This code needs to be thread safe but we don't have to be too careful + as the result is invariant. */ + if (!fixup) + { + int i; + unsigned int *iptr; + + /* Find the first "bl" branch in the offset search list. This is a + call to fixup or a magic branch to fixup at the beginning of the + trampoline template. The fixup function does the actual runtime + resolution of function descriptors. We only look for "bl" branches + with a 17-bit pc-relative displacement. */ + for (i = 0; i < NOFFSETS; i++) + { + iptr = (unsigned int *) (got[-2] + fixup_branch_offset[i]); + if ((*iptr & 0xfc00e000) == 0xe8000000) + break; + } + + /* This should not happen... */ + if (i == NOFFSETS) + return ~0; + + /* Extract the 17-bit displacement from the instruction. */ + iptr += SIGN_EXTEND (GET_FIELD (*iptr, 19, 28) | + GET_FIELD (*iptr, 29, 29) << 10 | + GET_FIELD (*iptr, 11, 15) << 11 | + GET_FIELD (*iptr, 31, 31) << 16, 17); + + /* Build a plabel for an indirect call to fixup. */ + fixup_plabel[0] = (unsigned int) iptr + 8; /* address of fixup */ + fixup_plabel[1] = got[-1]; /* ltp for fixup */ + fixup = (fixup_t) ((int) fixup_plabel | 3); + } + + /* Call fixup to resolve the function address. got[1] contains the + link_map pointer and plabel[1] the relocation offset. */ + fixup ((struct link_map *) got[1], plabel[1]); + + return plabel[0]; +} diff --git a/libgcc/config/pa/lib2funcs.S b/libgcc/config/pa/lib2funcs.S new file mode 100644 index 0000000..8aa398c --- /dev/null +++ b/libgcc/config/pa/lib2funcs.S @@ -0,0 +1,74 @@ +; Subroutines for calling unbound dynamic functions from within GDB for HPPA. +; Subroutines for out of line prologues and epilogues on for the HPPA +; Copyright (C) 1994, 1995, 1996, 2009 Free Software Foundation, Inc. + +; This file is part of GCC. + +; GCC is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 3, or (at your option) +; any later version. + +; GCC is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +; Under Section 7 of GPL version 3, you are granted additional +; permissions described in the GCC Runtime Library Exception, version +; 3.1, as published by the Free Software Foundation. + +; You should have received a copy of the GNU General Public License and +; a copy of the GCC Runtime Library Exception along with this program; +; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +; <http://www.gnu.org/licenses/>. + +#if !defined(__pro__) && !defined(__rtems__) + .SPACE $PRIVATE$ + .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31 + .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82 + .SPACE $TEXT$ + .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44 + .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY + .SUBSPA $MILLICODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=8 +#endif + .IMPORT $$dyncall,MILLICODE +#if !defined(__pro__) && !defined(__rtems__) + .SPACE $TEXT$ + .SUBSPA $CODE$ +#else + .text +#endif + +; Simply call with the address of the desired import stub in %r22 and +; arguments in the normal place (%r26-%r23 and stack slots). +; + .align 4 + .EXPORT __gcc_plt_call,ENTRY,PRIV_LEV=3,RTNVAL=GR +__gcc_plt_call + .PROC + .CALLINFO + .ENTRY + ; Our return address comes in %r31, not %r2! + stw %r31,-8(%r30) + + ; An inline version of dyncall so we don't have to worry + ; about long calls to millicode, PIC and other complexities. + bb,>=,n %r22,30,L$foo + depi 0,31,2,%r22 + ldw 4(%r22),%r19 + ldw 0(%r22),%r22 +L$foo + ldsid (%r22),%r1 + mtsp %r1,%sr0 + ble 0(%sr0,%r22) + copy %r31,%r2 + ldw -8(%r30),%r2 + + ; We're going to be returning to a stack address, so we + ; need to do an intra-space return. + ldsid (%rp),%r1 + mtsp %r1,%sr0 + be,n 0(%sr0,%rp) + .EXIT + .PROCEND diff --git a/libgcc/config/pa/linux-atomic.c b/libgcc/config/pa/linux-atomic.c new file mode 100644 index 0000000..2ae2426 --- /dev/null +++ b/libgcc/config/pa/linux-atomic.c @@ -0,0 +1,305 @@ +/* Linux-specific atomic operations for PA Linux. + Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + Based on code contributed by CodeSourcery for ARM EABI Linux. + Modifications for PA Linux by Helge Deller <deller@gmx.de> + +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/>. */ + +#define EFAULT 14 +#define EBUSY 16 +#define ENOSYS 251 + +/* All PA-RISC implementations supported by linux have strongly + ordered loads and stores. Only cache flushes and purges can be + delayed. The data cache implementations are all globally + coherent. Thus, there is no need to synchonize memory accesses. + + 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. */ + +/* A privileged instruction to crash a userspace program with SIGILL. */ +#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%sr0, %r0)") + +/* Determine kernel LWS function call (0=32-bit, 1=64-bit userspace). */ +#define LWS_CAS (sizeof(unsigned long) == 4 ? 0 : 1) + +/* Kernel helper for compare-and-exchange a 32-bit value. */ +static inline long +__kernel_cmpxchg (int oldval, int newval, int *mem) +{ + register unsigned long lws_mem asm("r26") = (unsigned long) (mem); + register long lws_ret asm("r28"); + register long lws_errno asm("r21"); + register int lws_old asm("r25") = oldval; + register int lws_new asm("r24") = newval; + asm volatile ( "ble 0xb0(%%sr2, %%r0) \n\t" + "ldi %5, %%r20 \n\t" + : "=r" (lws_ret), "=r" (lws_errno), "=r" (lws_mem), + "=r" (lws_old), "=r" (lws_new) + : "i" (LWS_CAS), "2" (lws_mem), "3" (lws_old), "4" (lws_new) + : "r1", "r20", "r22", "r23", "r29", "r31", "memory" + ); + if (__builtin_expect (lws_errno == -EFAULT || lws_errno == -ENOSYS, 0)) + ABORT_INSTRUCTION; + + /* If the kernel LWS call succeeded (lws_errno == 0), lws_ret contains + the old value from memory. If this value is equal to OLDVAL, the + new value was written to memory. If not, return -EBUSY. */ + if (!lws_errno && lws_ret != oldval) + lws_errno = -EBUSY; + + return lws_errno; +} + +#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 FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP) \ + int HIDDEN \ + __sync_fetch_and_##OP##_4 (int *ptr, int val) \ + { \ + int failure, tmp; \ + \ + do { \ + tmp = *ptr; \ + failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ + } while (failure != 0); \ + \ + return tmp; \ + } + +FETCH_AND_OP_WORD (add, , +) +FETCH_AND_OP_WORD (sub, , -) +FETCH_AND_OP_WORD (or, , |) +FETCH_AND_OP_WORD (and, , &) +FETCH_AND_OP_WORD (xor, , ^) +FETCH_AND_OP_WORD (nand, ~, &) + +#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH +#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH + +/* Implement both __sync_<op>_and_fetch and __sync_fetch_and_<op> for + subword-sized quantities. */ + +#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \ + TYPE HIDDEN \ + NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val) \ + { \ + int *wordptr = (int *) ((unsigned long) ptr & ~3); \ + unsigned int mask, shift, oldval, newval; \ + int failure; \ + \ + shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ + mask = MASK_##WIDTH << shift; \ + \ + do { \ + oldval = *wordptr; \ + newval = ((PFX_OP (((oldval & mask) >> shift) \ + INF_OP (unsigned int) val)) << shift) & mask; \ + newval |= oldval & ~mask; \ + failure = __kernel_cmpxchg (oldval, newval, wordptr); \ + } while (failure != 0); \ + \ + return (RETURN & mask) >> shift; \ + } + +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) + +#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \ + int HIDDEN \ + __sync_##OP##_and_fetch_4 (int *ptr, int val) \ + { \ + int tmp, failure; \ + \ + do { \ + tmp = *ptr; \ + failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ + } while (failure != 0); \ + \ + return PFX_OP (tmp INF_OP val); \ + } + +OP_AND_FETCH_WORD (add, , +) +OP_AND_FETCH_WORD (sub, , -) +OP_AND_FETCH_WORD (or, , |) +OP_AND_FETCH_WORD (and, , &) +OP_AND_FETCH_WORD (xor, , ^) +OP_AND_FETCH_WORD (nand, ~, &) + +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) + +int HIDDEN +__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval) +{ + int actual_oldval, fail; + + while (1) + { + actual_oldval = *ptr; + + if (__builtin_expect (oldval != actual_oldval, 0)) + return actual_oldval; + + fail = __kernel_cmpxchg (actual_oldval, newval, ptr); + + if (__builtin_expect (!fail, 1)) + return actual_oldval; + } +} + +#define SUBWORD_VAL_CAS(TYPE, WIDTH) \ + TYPE HIDDEN \ + __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ + TYPE newval) \ + { \ + int *wordptr = (int *)((unsigned long) ptr & ~3), fail; \ + unsigned int mask, shift, actual_oldval, actual_newval; \ + \ + shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ + mask = MASK_##WIDTH << shift; \ + \ + while (1) \ + { \ + actual_oldval = *wordptr; \ + \ + if (__builtin_expect (((actual_oldval & mask) >> shift) \ + != (unsigned int) oldval, 0)) \ + return (actual_oldval & mask) >> shift; \ + \ + actual_newval = (actual_oldval & ~mask) \ + | (((unsigned int) newval << shift) & mask); \ + \ + fail = __kernel_cmpxchg (actual_oldval, actual_newval, \ + wordptr); \ + \ + if (__builtin_expect (!fail, 1)) \ + return (actual_oldval & mask) >> shift; \ + } \ + } + +SUBWORD_VAL_CAS (unsigned short, 2) +SUBWORD_VAL_CAS (unsigned char, 1) + +typedef unsigned char bool; + +bool HIDDEN +__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval) +{ + int failure = __kernel_cmpxchg (oldval, newval, ptr); + return (failure == 0); +} + +#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \ + bool HIDDEN \ + __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ + TYPE newval) \ + { \ + TYPE actual_oldval \ + = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \ + return (oldval == actual_oldval); \ + } + +SUBWORD_BOOL_CAS (unsigned short, 2) +SUBWORD_BOOL_CAS (unsigned char, 1) + +int HIDDEN +__sync_lock_test_and_set_4 (int *ptr, int val) +{ + int failure, oldval; + + do { + oldval = *ptr; + failure = __kernel_cmpxchg (oldval, val, ptr); + } while (failure != 0); + + return oldval; +} + +#define SUBWORD_TEST_AND_SET(TYPE, WIDTH) \ + TYPE HIDDEN \ + __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \ + { \ + int failure; \ + unsigned int oldval, newval, shift, mask; \ + int *wordptr = (int *) ((unsigned long) ptr & ~3); \ + \ + shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ + mask = MASK_##WIDTH << shift; \ + \ + do { \ + oldval = *wordptr; \ + newval = (oldval & ~mask) \ + | (((unsigned int) val << shift) & mask); \ + failure = __kernel_cmpxchg (oldval, newval, wordptr); \ + } while (failure != 0); \ + \ + return (oldval & mask) >> shift; \ + } + +SUBWORD_TEST_AND_SET (unsigned short, 2) +SUBWORD_TEST_AND_SET (unsigned char, 1) + +#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \ + void HIDDEN \ + __sync_lock_release_##WIDTH (TYPE *ptr) \ + { \ + *ptr = 0; \ + } + +SYNC_LOCK_RELEASE (int, 4) +SYNC_LOCK_RELEASE (short, 2) +SYNC_LOCK_RELEASE (char, 1) diff --git a/libgcc/config/pa/quadlib.c b/libgcc/config/pa/quadlib.c new file mode 100644 index 0000000..2c11600 --- /dev/null +++ b/libgcc/config/pa/quadlib.c @@ -0,0 +1,245 @@ +/* Subroutines for long double support. + Copyright (C) 2000, 2002, 2004, 2005, 2006, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +/* HPUX TFmode compare requires a library call to _U_Qfcmp. It takes + a magic number as its third argument which indicates what to do. + The return value is an integer to be compared against zero. The + comparison conditions are the same as those listed in Table 8-12 + of the PA-RISC 2.0 Architecture book for the fcmp instruction. */ + +/* Raise FP_INVALID on SNaN as a side effect. */ +#define QCMP_INV 1 + +/* Comparison relations. */ +#define QCMP_UNORD 2 +#define QCMP_EQ 4 +#define QCMP_LT 8 +#define QCMP_GT 16 + +int _U_Qfcmp (long double a, long double b, int); +long _U_Qfcnvfxt_quad_to_sgl (long double); + +int _U_Qfeq (long double, long double); +int _U_Qfne (long double, long double); +int _U_Qfgt (long double, long double); +int _U_Qfge (long double, long double); +int _U_Qflt (long double, long double); +int _U_Qfle (long double, long double); +int _U_Qfltgt (long double, long double); +int _U_Qfunle (long double, long double); +int _U_Qfunlt (long double, long double); +int _U_Qfunge (long double, long double); +int _U_Qfungt (long double, long double); +int _U_Qfuneq (long double, long double); +int _U_Qfunord (long double, long double); +int _U_Qford (long double, long double); + +int _U_Qfcomp (long double, long double); + +long double _U_Qfneg (long double); +long double _U_Qfcopysign (long double, long double); + +#ifdef __LP64__ +int __U_Qfcnvfxt_quad_to_sgl (long double); +#endif +unsigned int _U_Qfcnvfxt_quad_to_usgl(long double); +long double _U_Qfcnvxf_usgl_to_quad (unsigned int); +unsigned long long _U_Qfcnvfxt_quad_to_udbl(long double); +long double _U_Qfcnvxf_udbl_to_quad (unsigned long long); + +int +_U_Qfeq (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_EQ) != 0); +} + +int +_U_Qfne (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_EQ) == 0); +} + +int +_U_Qfgt (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_GT) != 0); +} + +int +_U_Qfge (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_GT) != 0); +} + +int +_U_Qflt (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_LT) != 0); +} + +int +_U_Qfle (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_LT) != 0); +} + +int +_U_Qfltgt (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_LT | QCMP_GT) != 0); +} + +int +_U_Qfunle (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ | QCMP_LT) != 0); +} + +int +_U_Qfunlt (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_LT) != 0); +} + +int +_U_Qfunge (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ | QCMP_GT) != 0); +} + +int +_U_Qfungt (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_GT) != 0); +} + +int +_U_Qfuneq (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ) != 0); +} + +int +_U_Qfunord (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD) != 0); +} + +int +_U_Qford (long double a, long double b) +{ + return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_LT | QCMP_GT) != 0); +} + +int +_U_Qfcomp (long double a, long double b) +{ + if (_U_Qfcmp (a, b, QCMP_EQ) == 0) + return 0; + + return (_U_Qfcmp (a, b, QCMP_UNORD | QCMP_EQ | QCMP_GT) != 0 ? 1 : -1); +} + +/* Negate long double A. */ +long double +_U_Qfneg (long double a) +{ + union + { + long double ld; + int i[4]; + } u; + + u.ld = a; + u.i[0] ^= 0x80000000; + return u.ld; +} + +/* Return long double A with sign changed to sign of long double B. */ +long double +_U_Qfcopysign (long double a, long double b) +{ + union + { + long double ld; + int i[4]; + } ua, ub; + + ua.ld = a; + ub.ld = b; + ua.i[0] &= 0x7fffffff; + ua.i[0] |= (0x80000000 & ub.i[0]); + return ua.ld; +} + +#ifdef __LP64__ +/* This routine is only necessary for the PA64 port; for reasons unknown + _U_Qfcnvfxt_quad_to_sgl returns the integer in the high 32bits of the + return value. Ugh. */ +int +__U_Qfcnvfxt_quad_to_sgl (long double a) +{ + return _U_Qfcnvfxt_quad_to_sgl (a) >> 32; +} +#endif + +/* HP only has signed conversion in the C library, so need to synthesize + unsigned versions. */ +unsigned int +_U_Qfcnvfxt_quad_to_usgl (long double a) +{ + extern long long _U_Qfcnvfxt_quad_to_dbl (long double a); + return (unsigned int) _U_Qfcnvfxt_quad_to_dbl (a); +} + +long double +_U_Qfcnvxf_usgl_to_quad (unsigned int a) +{ + extern long double _U_Qfcnvxf_dbl_to_quad (long long); + return _U_Qfcnvxf_dbl_to_quad ((long long) a); +} + +typedef union { + unsigned long long u[2]; + long double d[1]; +} quad_type; + +unsigned long long +_U_Qfcnvfxt_quad_to_udbl (long double a) +{ + extern quad_type _U_Qfcnvfxt_quad_to_quad (long double a); + quad_type u; + u = _U_Qfcnvfxt_quad_to_quad(a); + return u.u[1]; +} + +long double +_U_Qfcnvxf_udbl_to_quad (unsigned long long a) +{ + extern long double _U_Qfcnvxf_quad_to_quad (quad_type a); + quad_type u; + u.u[0] = 0; + u.u[1] = a; + return _U_Qfcnvxf_quad_to_quad (u); +} diff --git a/libgcc/config/pa/t-hpux b/libgcc/config/pa/t-hpux new file mode 100644 index 0000000..fcf93ab --- /dev/null +++ b/libgcc/config/pa/t-hpux @@ -0,0 +1,3 @@ +LIB2ADD = $(srcdir)/config/pa/lib2funcs.S $(srcdir)/config/pa/quadlib.c + +HOST_LIBGCC2_CFLAGS += -frandom-seed=fixed-seed diff --git a/libgcc/config/pa/t-hpux10 b/libgcc/config/pa/t-hpux10 new file mode 100644 index 0000000..5620f31 --- /dev/null +++ b/libgcc/config/pa/t-hpux10 @@ -0,0 +1 @@ +HOST_LIBGCC2_CFLAGS += -D_T_HPUX10 diff --git a/libgcc/config/pa/t-linux b/libgcc/config/pa/t-linux index d396bf7..2157de9 100644 --- a/libgcc/config/pa/t-linux +++ b/libgcc/config/pa/t-linux @@ -1,6 +1,10 @@ #Plug millicode routines into libgcc.a We want these on both native and #cross compiles. We use the "64-bit" routines because the "32-bit" code #is broken for certain corner cases. - LIB1ASMSRC = pa/milli64.S LIB1ASMFUNCS = _divI _divU _remI _remU _div_const _mulI _dyncall + +HOST_LIBGCC2_CFLAGS += -DELF=1 -DLINUX=1 + +LIB2ADD = $(srcdir)/config/pa/fptr.c +LIB2ADD_ST = $(srcdir)/config/pa/linux-atomic.c diff --git a/libgcc/config/pa/t-linux64 b/libgcc/config/pa/t-linux64 index 6cb9806..1d0a6ad 100644 --- a/libgcc/config/pa/t-linux64 +++ b/libgcc/config/pa/t-linux64 @@ -2,3 +2,7 @@ # cross compiles. # FIXME: Explain. LIB1ASMFUNCS := $(filter-out _dyncall, $(LIB1ASMFUNCS)) + +LIB2ADD_ST = $(srcdir)/config/pa/linux-atomic.c + +HOST_LIBGCC2_CFLAGS += -Dpa64=1 -DELF=1 diff --git a/libgcc/config/pa/t-pa64 b/libgcc/config/pa/t-pa64 new file mode 100644 index 0000000..98f28ed --- /dev/null +++ b/libgcc/config/pa/t-pa64 @@ -0,0 +1,3 @@ +LIB2ADD = $(srcdir)/config/pa/quadlib.c + +HOST_LIBGCC2_CFLAGS += -Dpa64=1 -DELF=1 -mlong-calls diff --git a/libgcc/config/pdp11/t-pdp11 b/libgcc/config/pdp11/t-pdp11 new file mode 100644 index 0000000..bcd88e4 --- /dev/null +++ b/libgcc/config/pdp11/t-pdp11 @@ -0,0 +1,8 @@ +LIB2ADD = $(srcdir)/udivmod.c \ + $(srcdir)/udivmodsi4.c \ + $(srcdir)/memcmp.c \ + $(srcdir)/memcpy.c \ + $(srcdir)/memmove.c \ + $(srcdir)/memset.c + +HOST_LIBGCC2_CFLAGS = -O2 -mfloat32 diff --git a/libgcc/config/picochip/adddi3.S b/libgcc/config/picochip/adddi3.S new file mode 100644 index 0000000..77373ed --- /dev/null +++ b/libgcc/config/picochip/adddi3.S @@ -0,0 +1,194 @@ +// picoChip ASM file +// +// Support for 64-bit addition. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Hariharan Sandanagobalane (hariharan@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.align 8 +.global __adddi3 +__adddi3: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &__adddi3 = 12 bytes + + // The first operand of add is completely in registers r[2-5] + // The second operand of sub is in stack FP(0-3) + // and result need to be written pointed to by the register r0. + // All we need to do is to load the appropriate values, add them + // appropriately (with add or addc ) and then store the values back. + + ldw (FP)0, r1 + stl r[7:6], (FP)-1 + add.0 r2, r1, r6 + ldw (FP)1, r1 + addc.0 r3, r1, r7 + ldl (FP)1, r[3:2] + stl r[7:6], (r0)0 + addc.0 r4, r2, r6 + addc.0 r5, r3, r7 + stl r[7:6], (r0)1 + jr (r12) +=-> ldl (FP)-1, r[7:6] + +_picoMark_FUNCTION_END= + +// picoChip Function Epilogue : __adddi3 + + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0xe // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#61# 16#64# 16#64# 16#63# 16#69# 16#33# 16#0# // Function name `_adddi3' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile diff --git a/libgcc/config/picochip/ashlsi3.S b/libgcc/config/picochip/ashlsi3.S new file mode 100644 index 0000000..688cd8d --- /dev/null +++ b/libgcc/config/picochip/ashlsi3.S @@ -0,0 +1,193 @@ +// picoChip ASM file +// picoChip ASM file +// +// Support for 32-bit arithmetic shift left. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Hariharan Sandanagobalane (hariharan@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.global ___ashlsi3 +___ashlsi3: +_picoMark_FUNCTION_BEGIN= +// picoChip Function Prologue : &___ashlsi3 = 0 bytes + + // if (R2 > 15) goto _L2 + SUB.0 15,R2,r15 + JMPLT _L2 +=-> SUB.0 16,R2,R5 // R5 := R5 - R4 (HI) + + LSL.0 R1,R2,R1 // R3 := R1 << R2 + LSL.0 R0,R2,R4 // R2 := R0 << R2 + + LSR.0 R0,R5,R5 // R5 := R12 >> R5 NEED TO CHECK - HARI + OR.0 R5,R1,R5 // R3 := R5 IOR R0 (HI) + SUB.0 R2,0,r15 + COPYNE R5,R1 + JR (R12) // Return to caller +=-> COPY.0 R4,R0 + +_L2: + LSL.0 R0,R2,R1 // R3 := R0 << R2 + JR (R12) // Return to caller +=-> COPY.0 0,R0 // R2 := 0 (short constant) + +_picoMark_FUNCTION_END= + +// picoChip Function Epilogue : __ashlsi3 + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#61# 16#73# 16#68# 16#6c# 16#73# 16#69# 16#33# 16#0# // Function name `_ashlsi3' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile diff --git a/libgcc/config/picochip/ashlsi3.c b/libgcc/config/picochip/ashlsi3.c new file mode 100644 index 0000000..600461c --- /dev/null +++ b/libgcc/config/picochip/ashlsi3.c @@ -0,0 +1,82 @@ +/* + +picoChip GCC support for 32-bit shift left. + +Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +Contributed by Picochip Ltd. +Maintained by Daniel Towner (daniel.towner@picochip.com) + +This file 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. + +This file 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/>. */ + +#ifndef PICOCHIP +#error "Intended for compilation for PICOCHIP only." +#endif + +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); + +typedef struct USIstruct { + UHItype low, high; +} USIstruct; + +typedef union USIunion { + USItype l; + USIstruct s; +} USIunion; + +USItype __ashlsi3(USIunion value, HItype count) { + USIunion result; + int temp; + + /* Ignore a zero count until we get into the (count < 16) + clause. This is slightly slower when shifting by zero, but faster + and smaller in all other cases (due to the better scheduling + opportunities available by putting the test near computational + instructions. */ + /* if (count == 0) return value.l; */ + + if (count < 16) { + /* Shift low and high words by the count. */ + result.s.low = value.s.low << count; + result.s.high = value.s.high << count; + + /* There is now a hole in the lower `count' bits of the high + word. Shift the upper `count' bits of the low word into the + high word. This is only required when the count is non-zero. */ + if (count != 0) { + temp = 16 - count; + temp = value.s.low >> temp; + result.s.high |= temp; + } + + } else { + /* Shift the lower word of the source into the upper word of the + result, and zero the result's lower word. */ + count -= 16; + result.s.high = value.s.low << count; + result.s.low = 0; + + } + + return result.l; + +} + diff --git a/libgcc/config/picochip/ashrsi3.S b/libgcc/config/picochip/ashrsi3.S new file mode 100644 index 0000000..fddd70b --- /dev/null +++ b/libgcc/config/picochip/ashrsi3.S @@ -0,0 +1,202 @@ +// picoChip ASM file +// +// Support for 32-bit arithmetic shift right. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Hariharan Sandanagobalane (hariharan@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.global ___ashrsi3 +___ashrsi3: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &___ashrsi3 = 0 bytes + + // if (R2 > 15) goto _L2 + SUB.0 15,R2,r15 + JMPLT _L2 +=-> COPY.0 R1,R3 + + LSR.0 R1,R2,R1 // R1 := R1 >> R2 + // if (R2 == 0) goto _L4 + SUB.0 R2,0,r15 + JMPEQ _L4 +=-> LSR.0 R0,R2,R0 // R2 := R0 >> R2 + + SUB.0 16,R2,R4 // R4 := R4 - R2 (HI) + ASR.0 R3,15,R5 // R5 = R1 >>{arith} 15 + LSL.0 R5,R4,R5 // R5 := R5 << R4 + LSL.0 R3,R4,R4 // R4 := R1 << R4 + OR.0 R5,R1,R1 // R3 := R5 IOR R3 (HI) + BRA _L4 + =-> OR.0 R4,R0,R0 // R2 := R4 IOR R0 (HI) +_L2: + ASR.0 R1,15,R1 // R4 = R1 >>{arith} 15 + SUB.0 16,R2,R5 // R5 := R5 - R2 (HI) + LSR.0 R3,R2,R0 // R2 := R1 >> R2 + LSL.0 R1,R5,R5 // R5 := R4 << R5 + OR.0 R5,R0,R5 // R2 := R5 IOR R2 (HI) + SUB.0 R2,16,r15 // R5 := R5 - R2 (HI) + COPYNE R5,R0 +_L4: + JR (R12) // Return to caller + +_picoMark_FUNCTION_END= + +// picoChip Function Epilogue : __ashrsi3 +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#61# 16#73# 16#68# 16#72# 16#73# 16#69# 16#33# 16#0# // Function name `_ashrsi3' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/ashrsi3.c b/libgcc/config/picochip/ashrsi3.c new file mode 100644 index 0000000..4f1567b --- /dev/null +++ b/libgcc/config/picochip/ashrsi3.c @@ -0,0 +1,113 @@ +/* + +picoChip GCC support for 32-bit arithmetic shift right. + +Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +Contributed by Picochip Ltd. +Maintained by Daniel Towner (daniel.towner@picochip.com) + +This file 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. + +This file 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/>. */ + +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); + +typedef struct USIstruct { + UHItype low, high; +} USIstruct; + +typedef union USIunion { + USItype l; + USIstruct s; +} USIunion; + +USItype __ashrsi3(USIunion value, HItype count) { + USIunion result; + int temp; + int wordOfSignBits; + + /* Ignore a zero count until we get into the (count < 16) + clause. This is slightly slower when shifting by zero, but faster + and smaller in all other cases (due to the better scheduling + opportunities available by putting the test near computational + instructions. */ + /* if (count == 0) return value.l; */ + + if (count < 16) { + /* Shift low and high words by the count. The high word must use + an arithmetic shift. There is no arithmetic shift-right by + variable, so synthesise it. */ + int signWord; + int reverseCount; + + /* Shift low and high parts by the count. The upper word now has + invalid signed bits. */ + result.s.low = value.s.low >> count; + result.s.high = value.s.high >> count; + + if (count != 0) { + + reverseCount = 16 - count; + + /* Given a word of sign bits, shift back left to create the + destination sign bits. */ + wordOfSignBits = __builtin_asri(value.s.high, 15); + signWord = wordOfSignBits << reverseCount; + result.s.high |= signWord; + + /* There is now a hole in the upper `count' bits of the low + word. Shift the lower `count' bits of the upper word into the + low word. */ + temp = value.s.high << reverseCount; + result.s.low |= temp; + } + + } else { + int signWord; + + /* Shift is greater than one word, so top word will always be set + to sign bits, and bottom word will be shifted from top word. */ + result.s.low = value.s.high >> count; + result.s.high = __builtin_asri(value.s.high, 15); + + if (count != 16) { + + /* Shift the upper word of the source into the lower word of the + result. Arithmetically shift the upper word as well, to retain + the sign. This shift must be synthesised, as no such shift + exists in the instruction set. */ + int signWord; + + + /* Given a complete word of sign-bits, shift this back left to + create the destination sign bits. */ + signWord = result.s.high << (16 - count); + // signWord = wordOfSignBits << (16 - count); + + /* Insert the sign bits to the result's low word. */ + result.s.low |= signWord; + + } + + } + + return result.l; + +} diff --git a/libgcc/config/picochip/clzsi2.S b/libgcc/config/picochip/clzsi2.S new file mode 100644 index 0000000..d5c99aa --- /dev/null +++ b/libgcc/config/picochip/clzsi2.S @@ -0,0 +1,189 @@ +// Copyright (C) 2008, 2011 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. +// +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. +// +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// picoChip ASM file +//.file "clzsi2.S" + +.section .text + +.global __clzsi2 +__clzsi2: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &__clzsi2 = 0 bytes + + // What value should be operated on? If the top word is empty + // then count the bits in the bottom word, and add 16. If the + // top word is not empty, then count the bits in the top word. + + // R4 stores the constant 0 + + sub.0 R1,0,r15 \ copy.1 16,r2 + copyeq r0,r1 + copyne 0,r2 + + // R1 now stores value to count, and R2 stores current bit offset. + sbc r1,r0 + asr.0 r1,15,r15 \ add.1 r0,1,r0 + jr (lr) \ copyne 0,r0 +=-> add.0 r0,r2,r0 + +_picoMark_FUNCTION_END= + +// picoChip Function Epilogue : __clzsi2 + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5F# 16#63# 16#6C# 16#7A# 16#73# 16#69# 16#32# 16#0# // Function name `_clzsi2' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/cmpsi2.S b/libgcc/config/picochip/cmpsi2.S new file mode 100644 index 0000000..95322f3 --- /dev/null +++ b/libgcc/config/picochip/cmpsi2.S @@ -0,0 +1,212 @@ +// picoChip ASM file +//.file "ucmpsi2.c" +// +// Support for 32-bit signed compare. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Daniel Towner (daniel.towner@picochip.com) +// +// This file 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. +// +// This file 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/>. + +// Compiled from the following, and then hand optimised. +// +// int __cmpsi2 (USItype x, USItype y) +// { +// +// SIunion lx; lx.l = x; +// SIunion ly; ly.l = y; +// +// if (lx.s.high < ly.s.high) +// return 0; +// else if (lx.s.high > ly.s.high) +// return 2; +// if (lx.s.low < ly.s.low) +// return 0; +// else if (lx.s.low > ly.s.low) +// return 2; +// return 1; +// } + +.section .text + +.align 8 +.global ___cmpsi2 +___cmpsi2: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &___cmpsi2 = 0 bytes + + SUB.0 R1,R3,r15 + + BLT _L1 +=-> SUB.0 R3,R1,r15 \ COPY.1 0,R5 + + BLT _L1 +=-> SUB.0 R0,R2,r15 \ COPY.1 2,R5 + + BLO _L1 +=-> SUB.0 R2,R0,r15 \ COPY.1 0,R5 + + BLO _L1 +=-> COPY.0 2,R5 + + COPY.0 1,R5 +_L1: + JR (R12) +=-> COPY.0 R5,R0 + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : __cmpsi2 +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#5f# 16#63# 16#6d# 16#70# 16#73# 16#69# 16#32# 16#0# // Function name `__cmpsi2' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/divmod15.S b/libgcc/config/picochip/divmod15.S new file mode 100644 index 0000000..d314b3b --- /dev/null +++ b/libgcc/config/picochip/divmod15.S @@ -0,0 +1,261 @@ +// picoChip ASM file +// +// Support for 16-bit unsigned division/modulus. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Daniel Towner (daniel.towner@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.global __divmod15 +__divmod15: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &__divmod15 = 0 bytes + + // The picoChip instruction set has a divstep instruction which + // is used to perform one iteration of a binary division algorithm. + // The instruction allows 16-bit signed division to be implemented. + // It does not directly allow 16-bit unsigned division to be + // implemented. Thus, this function pulls out the common division + // iteration for 15-bits unsigned, and then special wrappers + // provide the logic to change this into a 16-bit signed or + // unsigned division, as appropriate. This allows the two + // versions of division to share a common implementation, reducing + // code size when the two are used together. It also reduces + // the maintenance overhead. + + // Input: + // r0 - dividend + // r1 - divisor + // Output: + // r0 - quotient + // r1 - remainder + // R5 is unused + + // Check for special cases. The emphasis is on detecting these as + // quickly as possible, so that the main division can be started. If + // the user requests division by one, division by self, and so on + // then they will just have to accept that this won't be particularly + // quick (relatively), whereas a real division (e.g., dividing a + // large value by a small value) will run as fast as possible + // (i.e., special case detection should not slow down the common case) + // + // Special cases to consider: + // + // Division by zero. + // Division of zero. + // Inputs are equal + // Divisor is bigger than dividend + // Division by power of two (can be shifted instead). + // Division by 1 (special case of power of two division) + // + // Division/modulus by zero is undefined (ISO C:6.5.5), so + // don't bother handling this special case. + // + // The special cases of division by a power of 2 are ignored, since + // they cause the general case to slow down. Omitting these + // special cases also reduces code size considerably. + + // Handle divisor >= dividend separately. Note that this also handles + // the case where the dividend is zero. Note that the flags must be + // preserved, since they are also used at the branch destination. + sub.0 r1,r0,r15 + sbc r0,r2 \ bge divisorGeDividend +=-> sbc r1,r4 + + // Compute the shift count. The amount by which the divisor + // must be shifted left to be aligned with the dividend. + sub.0 r4,r2,r3 + + // Align the divisor to the dividend. Execute a divstep (since at + // least one will always be executed). Skip the remaining loop + // if the shift count is zero. + lsl.0 r1,r3,r1 \ beq skipLoop +=-> divstep r0,r1 \ add.1 r3,1,r2 + + // Execute the divstep loop until temp is 0. This assumes that the + // loop count is at least one. + sub.0 r3,1,r4 +divLoop: + divstep r0,r1 \ bne divLoop +=-> sub.0 r4,1,r4 + +skipLoop: + + // The top bits of the result are the remainder. The bottom + // bits are the quotient. + lsr.0 r0,r2,r1 \ sub.1 16,r2,r4 + jr (lr ) \ lsl.0 r0,r4,r0 +=-> lsr.0 r0,r4,r0 + +// Special case. + +divisorGeDividend: + // The divisor is greater than or equal to the dividend. The flags + // indicate which of these alternatives it is. The COPYNE can be used + // to set the result appropriately, without introducing any more + // branches. + copy.0 r0,r1 \ copy.1 0,r0 + jr (lr) \ copyeq r0,r1 +=-> copyeq 1,r0 + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : __divmod15 + + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#64# 16#69# 16#76# 16#6d# 16#6f# 16#64# 16#31# 16#35# 16#0# // Function name `_divmod15' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/divmodhi4.S b/libgcc/config/picochip/divmodhi4.S new file mode 100644 index 0000000..9dad674 --- /dev/null +++ b/libgcc/config/picochip/divmodhi4.S @@ -0,0 +1,246 @@ +// picoChip ASM file +// +// Support for 16-bit signed division/modulus. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Daniel Towner (daniel.towner@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.align 8 +.global __divmodhi4 +__divmodhi4: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &__divmodhi4 = 4 bytes + + // 16-bit signed division. Most of the special cases are dealt + // with by the 15-bit signed division library (e.g., division by + // zero, division by 1, and so on). This wrapper simply inverts + // any negative inputs, calls the 15-bit library, and flips any + // results as necessary. The + // only special cases to be handled here are where either the + // divisor or the dividend are the maximum negative values. + + // Encode r5 with a bit pattern which indicates whether the + // outputs of the division must be negated. The MSB will be set + // to the sign of the dividend (which controls the remainder's + // sign), while the LSB will store the XOR of the two signs, + // which indicates the quotient's sign. R5 is not modified by the + // 15-bit divmod routine. + sub.0 r1,16#8000#,r15 \ asr.1 r0,15,r4 + beq divisorIsLargestNegative \ lsr.0 r1,15,r3 +=-> sub.0 r0,16#8000#,r15 \ xor.1 r3,r4,r5 + + // Handle least negative dividend with a special case. Note that the + // absolute value of the divisor is also computed here. + add.0 [asr r1,15],r1,r3 \ beq dividendIsLargestNegative +=-> xor.0 [asr r1,15],r3,r1 \ stw lr,(fp)-1 + + // Compute the absolute value of the dividend, and call the main + // divide routine. + add.0 r4,r0,r2 \ jl (&__divmod15) // fn_call &__divmod15 +=-> xor.0 r4,r2,r0 + +handleNegatedResults: + // Speculatively store the negation of the results. + sub.0 0,r0,r2 \ sub.1 0,r1,r3 + + // Does the quotient need negating? The LSB indicates this. + and.0 r5,1,r15 \ ldw (fp)-1,lr + copyne r2,r0 + + asr.0 r5,15,r15 \ jr (lr) +=-> copyne r3,r1 + +dividendIsLargestNegative: + + // Divide the constant -32768. Use the Hacker's Delight + // algorithm (i.e., ((dividend / 2) / divisor) * 2) gives + // approximate answer). This code is a special case, so no + // great effort is made to make it fast, only to make it + // small. + + lsr.0 r0,1,r0 \ jl (&__divmod15) // fn_call &__divmod15 +=-> stw r1,(fp)-2 + + // Load the original divisor, and compute the new quotient and + // remainder. + lsl.0 r0,1,r0 \ ldw (fp)-2,r3 + lsl.0 r1,1,r1 // Fill stall slot + + // The error in the quotient is 0 or 1. The error can be determined + // by comparing the remainder to the original divisor. If the + // remainder is bigger, then an error of 1 has been introduced, + // which must be fixed. + sub.0 r1,r3,r15 + blo noCompensationForError +=-> nop + add.0 r0,1,r0 \ sub.1 r1,r3,r1 +noCompensationForError: + bra handleNegatedResults +=-> nop + +divisorIsLargestNegative: + // The flags indicate whether the dividend is also the maximum negative + copy.0 r0,r1 \ copy.1 0,r0 + copyeq r0,r1 \ jr (lr) +=-> copyeq 1,r0 + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : __divmodhi4 + + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x4 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#64# 16#69# 16#76# 16#6d# 16#6f# 16#64# 16#68# 16#69# 16#34# 16#0# // Function name `_divmodhi4' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ +.section .endFile diff --git a/libgcc/config/picochip/divmodsi4.S b/libgcc/config/picochip/divmodsi4.S new file mode 100644 index 0000000..4fc1acb --- /dev/null +++ b/libgcc/config/picochip/divmodsi4.S @@ -0,0 +1,233 @@ +// picoChip ASM file +// +// Support for 32-bit signed division/modulus. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Daniel Towner (daniel.towner@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.align 8 +.global __divmodsi4 +__divmodsi4: +_picoMark_FUNCTION_BEGIN= +// picoChip Function Prologue : &__divmodsi4 = 8 bytes + + // Note: optimising for size is preferred over optimising for speed. + + // Note: the frame is setup throughout the following instructions, + // and is complete at the point the udivmodsi4 function is called. + + // Note that R9 is encoded with a pattern which indicates + // whether the remainder and quotient should be negated on + // completion. The MSB is set to the sign of the dividend + // (i.e., the sign of the remainder), while the LSB encodes + // the XOR of the two input's signs (i.e., the sign of the + // quotient. + + // If dividend is negative, invert the dividend and flag. + ASR.0 r1,15,r4 + BEQ dividendNotNegative +=-> STL R[9:8],(FP)-2 + + // Dividend is negative - negate dividend. + SUB.0 0,R0,R0 + SUBB.0 0,R1,R1 + +dividendNotNegative: + + // If divisor is negative, invert the divisor. + AND.0 [lsr r3,15],1,r5 + SUB.0 R3,0, r15 + BGE divisorNotNegative +=-> XOR.0 r4,r5,r9 + + // Divisor is negative - negate divisor. + SUB.0 0,R2,R2 + SUBB.0 0,R3,R3 + +divisorNotNegative: + + STL R[13:12],(FP)-1 \ JL (&__udivmodsi4) +=-> SUB.0 FP,8,FP // udivmodsi expects the frame to be valid still. + + // The LSB of R9 indicates whether the quotient should be negated. + AND.0 r9,1,r15 + BEQ skipQuotientNegation +=-> LDL (FP)1,R[13:12] // Convenient point to restore link/fp + + SUB.0 0,R4,R4 + SUBB.0 0,R5,R5 + +skipQuotientNegation: + + // The MSB of R9 indicates whether the remainder should be negated. + ASR.0 R9,15,r15 + BEQ epilogue + + SUB.0 0,R6,R6 + SUBB.0 0,R7,R7 + +epilogue: + + JR (R12) +=-> LDL (FP)-2,R[9:8] + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : __divmodsi4 + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x8 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#64# 16#69# 16#76# 16#6d# 16#6f# 16#64# 16#73# 16#69# 16#34# 16#0# // Function name `_divmodsi4' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/longjmp.S b/libgcc/config/picochip/longjmp.S new file mode 100644 index 0000000..d2a80ac --- /dev/null +++ b/libgcc/config/picochip/longjmp.S @@ -0,0 +1,182 @@ +// picoChip ASM file +// +// Support for 32-bit arithmetic shift right. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Hariharan Sandanagobalane (hariharan@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.global _longjmp +_longjmp: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &_longjmp = 0 bytes + + LDL (R0)0, R[3:2] + LDL (R0)1, R[5:4] + LDL (R0)2, R[7:6] + LDL (R0)3, R[9:8] + LDL (R0)4, R[11:10] + LDL (R0)5, R[13:12] + LDW (R0)12, R14 + LDW (R0)13, R1 + JR (R12) +=-> COPY.0 1,R0 + +// picoChip Function Epilogue : longjmp +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#6c# 16#6f# 16#6e# 16#67# 16#6a# 16#6d# 16#70# 16#0# // Function name `longjmp' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/lshrsi3.S b/libgcc/config/picochip/lshrsi3.S new file mode 100644 index 0000000..4fc5390 --- /dev/null +++ b/libgcc/config/picochip/lshrsi3.S @@ -0,0 +1,190 @@ +// picoChip ASM file +// +// Support for 32-bit logical shift right. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Hariharan Sandanagobalane (hariharan@picochip.com) +// +// This file 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. +// +// This file 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/>. +.section .text + +.global ___lshrsi3 +___lshrsi3: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &___lshrsi3 = 4 bytes + + // if (R2 > 15) goto _L2 + SUB.0 15,R2,r15 + JMPLT _L2 +=-> SUB.0 16,R2,R5 // R5 := R5 - R2 (HI) + + LSR.0 R0,R2,R0 // R4 := R0 >> R2 + LSR.0 R1,R2,R3 // R3 := R1 >> R2 + // if (R2 == 0) goto _L4 + LSL.0 R1,R5,R5 // R5 := R1 << R5 + OR.0 R5,R0,R4 // R2 := R5 IOR R2 (HI) + SUB.0 R2,0,r15 + COPYNE R4,R0 // R0 := R2 + JR (R12) // Return to caller +=-> COPY.0 R3,R1 // R1 := R3 + +_L2: + LSR.0 R1,R2,R0 // R2 := R1 >> R2 + JR (R12) // Return to caller +=-> COPY.0 0,R1 // R3 := 0 (short constant) + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : __lshrsi3 + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x4 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#5f# 16#6c# 16#73# 16#68# 16#72# 16#72# 16#73# 16#69# 16#33# 16#0# // Function name `__lshrsi3' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ +.section .endFile diff --git a/libgcc/config/picochip/lshrsi3.c b/libgcc/config/picochip/lshrsi3.c new file mode 100644 index 0000000..fa32dc7 --- /dev/null +++ b/libgcc/config/picochip/lshrsi3.c @@ -0,0 +1,76 @@ +/* + +picoChip GCC support for 32-bit logical shift right. + +Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +Contributed by Picochip Ltd. +Maintained by Daniel Towner (daniel.towner@picochip.com) + +This file 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. + +This file 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/>. */ + +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); + +typedef struct USIstruct { + UHItype low, high; +} USIstruct; + +typedef union USIunion { + USItype l; + USIstruct s; +} USIunion; + +USItype __lshrsi3(USIunion value, HItype count) { + USIunion result; + int temp; + + /* Ignore a zero count until we get into the (count < 16) + clause. This is slightly slower when shifting by zero, but faster + and smaller in all other cases (due to the better scheduling + opportunities available by putting the test near computational + instructions. */ + + if (count < 16) { + /* Shift low and high words by the count. */ + result.s.low = value.s.low >> count; + result.s.high = value.s.high >> count; + + /* There is now a hole in the upper `count' bits of the low + word. Shift the lower `count' bits of the upper word into the + low word. This only works when count isn't zero. */ + if (count != 0) { + temp = value.s.high << (16 - count); + result.s.low |= temp; + } + + } else { + /* Shift the upper word of the source into the lower word of the + result, and zero the result's upper word. Note that we actually + ned to shift by (count - 16), but as we are only using the + bottom 4 bits, this is equivalent to shifting by count. */ + result.s.low = value.s.high >> count; + result.s.high = 0; + + } + + return result.l; + +} diff --git a/libgcc/config/picochip/parityhi2.S b/libgcc/config/picochip/parityhi2.S new file mode 100644 index 0000000..b9d0cdc --- /dev/null +++ b/libgcc/config/picochip/parityhi2.S @@ -0,0 +1,179 @@ +// picoChip ASM file +//.file "ucmpsi2.c" +// +// Support for parity checks. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Daniel Towner (daniel.towner@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.align 8 +.global ___parityhi2 +___parityhi2: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &___parityhi2 = 0 bytes + XOR.0 [LSR R0,8],R0,R0 + XOR.0 [LSR R0,4],R0,R0 + XOR.0 [LSR R0,2],R0,R0 + JR (R12) \ XOR.0 [LSR R0,1],R0,R0 +=-> AND.0 R0,1,R0 + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : __parityhi2 +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#5f# 16#70# 16#61# 16#72# 16#69# 16#74# 16#79# 16#68# 16#69# 16#32# 16#0# // Function name `__parityhi2' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/popcounthi2.S b/libgcc/config/picochip/popcounthi2.S new file mode 100644 index 0000000..2da618c --- /dev/null +++ b/libgcc/config/picochip/popcounthi2.S @@ -0,0 +1,201 @@ +// picoChip ASM file +//.file "popcounthi2.S" +// +// Support for 16-bit population count. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Daniel Towner (daniel.towner@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +// The following code (taken from a newsgroup posting) was compiled, and then +// hand assembled (a similar version is given in the Hacker's Delight +// book, chapter 5). +// +// int +// popcount (int value) +// { +// value = ((value & 0xAAAA) >> 1) + (value & 0x5555); +// value = ((value & 0xCCCC) >> 2) + (value & 0x3333); +// value = ((value & 0xF0F0) >> 4) + (value & 0x0F0F); +// return ((value & 0xFF00) >> 8) + (value & 0x00FF); +// } +// +// This assembly function is approx. 20x faster than a naive loop +// implementation of the population count, but about 30% bigger +// (45 bytes v. 34 bytes). + +.align 8 +.global ___popcounthi2 +___popcounthi2: + +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &___popcounthi2 = 0 bytes + + AND.0 [LSR R0,1],21845,R0 \ AND.1 R0,21845,R5 + ADD.0 R0,R5,R0 + AND.0 [LSR R0,2],13107,R0 \ AND.1 R0,13107,R5 + ADD.0 R0,R5,R0 \ COPY.1 1807,R2 + AND.0 [LSR R0,4],R2,R0 \ AND.1 R0,3855,R5 + ADD.0 R0,R5,R0 + JR (R12) \ AND.0 R0, 255, R5 +=-> ADD.0 [LSR R0,8],R5,R0 + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : ___popcounthi2 +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#5f# 16#70# 16#6f# 16#70# 16#63# 16#6f# 16#75# 16#6e# 16#74# 16#68# 16#69# 16#32# 16#0# // Function name `__popcounthi2' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/setjmp.S b/libgcc/config/picochip/setjmp.S new file mode 100644 index 0000000..247c715 --- /dev/null +++ b/libgcc/config/picochip/setjmp.S @@ -0,0 +1,182 @@ +// picoChip ASM file +// +// Support for 32-bit arithmetic shift right. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Hariharan Sandanagobalane (hariharan@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.global _setjmp +_setjmp: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &_setjmp = 0 bytes + + STL R[3:2],(R0)0 + STL R[5:4],(R0)1 + STL R[7:6],(R0)2 + STL R[9:8],(R0)3 + STL R[11:10],(R0)4 + STL R[13:12],(R0)5 + STW R14,(R0)12 + STW R1,(R0)13 + JR (R12) +=-> COPY.0 0,R0 + +// picoChip Function Epilogue : setjmp +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#73# 16#65# 16#74# 16#6a# 16#6d# 16#70# 16#0# // Function name `setjmp' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ + +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/subdi3.S b/libgcc/config/picochip/subdi3.S new file mode 100644 index 0000000..d1c833e --- /dev/null +++ b/libgcc/config/picochip/subdi3.S @@ -0,0 +1,191 @@ +// picoChip ASM file +// +// Support for 64-bit subtraction. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Hariharan Sandanagobalane (hariharan@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.align 8 +.global __subdi3 +__subdi3: + +_picoMark_FUNCTION_BEGIN= +// picoChip Function Prologue : &__subdi3 = 4 bytes + + // The first operand of sub is completely in registers r[2-5] + // The second operand of sub is in stack FP(0-3) + // and result need to be written pointed to by the register r0. + // All we need to do is to load the appropriate values, sub them + // appropriately (with sub or subb) and then store the values back. + ldw (FP)0, r1 + stl r[7:6], (FP)-1 + sub.0 r2, r1, r6 + ldw (FP)1, r1 + subb.0 r3, r1, r7 + ldl (FP)1, r[3:2] + stl r[7:6], (r0)0 + subb.0 r4, r2, r6 + subb.0 r5, r3, r7 + stl r[7:6], (r0)1 + jr (r12) +=-> ldl (FP)2, r[7:6] + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : __subdi3 + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x4 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#73# 16#75# 16#62# 16#64# 16#69# 16#33# 16#0# // Function name `_subdi3' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ +.section .endFile + diff --git a/libgcc/config/picochip/t-picochip b/libgcc/config/picochip/t-picochip index a596ec9..dd65f9e 100644 --- a/libgcc/config/picochip/t-picochip +++ b/libgcc/config/picochip/t-picochip @@ -5,5 +5,35 @@ LIB1ASMSRC = picochip/lib1funcs.S LIB1ASMFUNCS = _mulsc3 _divsc3 +# Compile the extra library functions. +LIB2ADD = \ + $(srcdir)/config/picochip/ashrsi3.S \ + $(srcdir)/config/picochip/ashlsi3.S \ + $(srcdir)/config/picochip/divmodhi4.S \ + $(srcdir)/config/picochip/udivmodhi4.S \ + $(srcdir)/config/picochip/divmodsi4.S \ + $(srcdir)/config/picochip/udivmodsi4.S \ + $(srcdir)/config/picochip/divmod15.S \ + $(srcdir)/config/picochip/ucmpsi2.S \ + $(srcdir)/config/picochip/cmpsi2.S \ + $(srcdir)/config/picochip/clzsi2.S \ + $(srcdir)/config/picochip/adddi3.S \ + $(srcdir)/config/picochip/subdi3.S \ + $(srcdir)/config/picochip/lshrsi3.S \ + $(srcdir)/config/picochip/parityhi2.S \ + $(srcdir)/config/picochip/popcounthi2.S + +# Special libgcc setup. Make single/double floating point the same, +# and use our own include files. +HOST_LIBGCC2_CFLAGS = -DDF=SF -I../../includes/ + +# Switch off all debugging for the embedded libraries. +# (embedded processors need small libraries by default). +# NOTE: If the debug level is increased, turn off instruction scheduling. +LIBGCC2_DEBUG_CFLAGS = -g0 + # Turn off the building of exception handling libraries. LIB2ADDEH = + +# Turn off ranlib on target libraries. +RANLIB_FOR_TARGET = cat diff --git a/libgcc/config/picochip/ucmpsi2.S b/libgcc/config/picochip/ucmpsi2.S new file mode 100644 index 0000000..10c03cf --- /dev/null +++ b/libgcc/config/picochip/ucmpsi2.S @@ -0,0 +1,209 @@ +// picoChip ASM file +//.file "ucmpsi2.c" +// +// Support for 32-bit unsigned compare. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Daniel Towner (daniel.towner@picochip.com) +// +// This file 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. +// +// This file 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/>. +// +// Compiled from the following, and then hand optimised. +// +// int __ucmpsi2 (USItype x, USItype y) +// { +// +// USIunion lx; lx.l = x; +// USIunion ly; ly.l = y; +// +// if (lx.s.high < ly.s.high) +// return 0; +// else if (lx.s.high > ly.s.high) +// return 2; +// if (lx.s.low < ly.s.low) +// return 0; +// else if (lx.s.low > ly.s.low) +// return 2; +// return 1; +// } + +.section .text + +.align 8 +.global ___ucmpsi2 +___ucmpsi2: +_picoMark_FUNCTION_BEGIN= +// picoChip Function Prologue : &___ucmpsi2 = 0 bytes + SUB.0 R1,R3,r15 + + BLO _L1 +=-> SUB.0 R3,R1,r15 \ COPY.1 0,R5 + + BLO _L1 +=-> SUB.0 R0,R2,r15 \ COPY.1 2,R5 + + BLO _L1 +=-> SUB.0 R2,R0,r15 \ COPY.1 0,R5 + + BLO _L1 +=-> COPY.0 2,R5 + + COPY.0 1,R5 +_L1: + JR (R12) +=-> COPY.0 R5,R0 // R0 := R5 + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : __ucmpsi2 +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#5f# 16#75# 16#63# 16#6d# 16#70# 16#73# 16#69# 16#32# 16#0# // Function name `__ucmpsi2' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/udivmodhi4.S b/libgcc/config/picochip/udivmodhi4.S new file mode 100644 index 0000000..ac16fae --- /dev/null +++ b/libgcc/config/picochip/udivmodhi4.S @@ -0,0 +1,238 @@ +// picoChip ASM file +// +// Support for 16-bit unsigned division/modulus. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Daniel Towner (daniel.towner@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.global __udivmodhi4 +__udivmodhi4: +_picoMark_FUNCTION_BEGIN= + +// picoChip Function Prologue : &__udivmodhi4 = 6 bytes + + // 16-bit unsigned division. The divstep function is only capable of + // handling 15-bit division (plus a sign to give 16-bits). It is not + // capable of handling unsigned division directly. Instead, take + // advantage of the special property that + // ((divisor / 2) / dividend) * 2 will be almost good enough. The + // error in the result is only 0 or 1, and this can be easily + // tested and corrected. A full description of the algorithm can + // be found in `Hacker's Delight', by Henry Warren, page 146. + + // Input: + // r0 - dividend + // r1 - divisor + // Output: + // r0 - quotient + // r1 - remainder + + // Note that the lr, and original inputs are speculatively saved. They + // will only be restored if the 15-bit division function is called. + + sub.0 r1,0,r15 \ stl r[0:1],(fp)-1 + bge divisorIs15bit +=-> sub.0 r0,r1,r2 \ stw lr,(fp)-3 + + // The divisor is >= 2^15. + bhs quotientIs1 + + // The dividend < divisor. The quotient is thus 0, and the + // remainder is the dividend. + copy.0 r0,r1 \ jr (lr) +=-> copy.0 0,r0 + +quotientIs1: + // The dividend >= divisor. The quotient is thus 1, and the + // remainder can be computed directly by subtraction (i.e., the + // result of the comparison already performed to branch here). + jr (lr) \ copy.0 r2,r1 +=-> copy.0 1,r0 + +divisorIs15bit: + // The divisor is < 2^15. + + // Divide the original dividend by 2, and call the 15-bit division. + // Note that the original dividend is stored in r5, which is + // known to be unused by the called function, so that + // a memory stall isn't introduced immediately after the + // function returns, to reload this value from memory. + + jl (&__divmod15) \ copy.0 r0,r5 // fn_call &__divmod15 +=-> lsr.0 r0,1,r0 + + // Compute the new quotient and remainder by multiplying them by 2. + // The remainder will be 1 out, if the original dividend was odd. + and.0 r5,1,r5 \ ldl (fp)-1,r[2:3] + add.0 [lsl r1,1],r5,r1 \ lsl.1 r0,1,r0 + + // The error in the quotient is 0 or 1. The error can be determined + // by comparing the remainder to the original divisor. If the + // remainder is bigger, then an error of 1 has been introduced. + sub.0 r1,r3,r15 \ ldw (fp)-3,lr + blo noCompensation +=-> nop + add.0 r0,1,r0 \ sub.1 r1,r3,r1 +noCompensation: + jr (lr) + +_picoMark_FUNCTION_END= +// picoChip Function Epilogue : udivmodhi4 + + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x6 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#75# 16#64# 16#69# 16#76# 16#6d# 16#6f# 16#64# 16#68# 16#69# 16#34# 16#0# // Function name `_udivmodhi4' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/picochip/udivmodsi4.S b/libgcc/config/picochip/udivmodsi4.S new file mode 100644 index 0000000..92c2a49 --- /dev/null +++ b/libgcc/config/picochip/udivmodsi4.S @@ -0,0 +1,318 @@ +// picoChip ASM file +// +// Support for 32-bit unsigned division/modulus. +// +// Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. +// Contributed by Picochip Ltd. +// Maintained by Daniel Towner (daniel.towner@picochip.com) +// +// This file 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. +// +// This file 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/>. + +.section .text + +.align 8 +.global __udivmodsi4 +__udivmodsi4: +_picoMark_FUNCTION_BEGIN= +// picoChip Function Prologue : &__udivmodsi4 = 24 bytes + + // Schedule the register saves alongside the special cases, so that + // if the special cases fail, the registers will have already + // been stored onto the stack. + SUB.0 R3,R1,r15 \ STL R[13:12],(FP)-1 + BHS skipCommonCase \ STL R[9:8],(FP)-4 +=-> SUB.0 R2,1,r15 \ STL R[11:10],(FP)-3 + +_L2: + // Flags set above, and in _L2 caller. + BNE restOfCode +=-> SUB.0 R3,0,r15 + BNE restOfCode +=-> COPY.0 R0,R4 \ COPY.1 R1,R5 + JR (R12) // Return to caller +=-> COPY.0 0,R6 \ COPY.1 0,R7 + // Never reach here + +skipCommonCase: + SUB.0 R3,R1,r15 + BNE _L3 // (Reversed branch) +=-> SUB.0 R2,R0,r15 // Must be set in delay slot, so ready by _L9 + +_L9: + BLO _L2 // (Reversed branch) +=-> SUB.0 R2,1,r15 + +_L3: + SUB.0 R2,R0,r15 + BEQ _L10 // (Reversed branch) +=-> SUB.0 R1,R3,r15 // Set flags for branch at _L10 + +_L4: + // greater than + COPY.0 0,R4 \ COPY.1 0,R5 \ JR (R12) // Return to caller +=-> COPY.0 R0,R6 \ COPY.1 R1,R7 + // Doesn't reach here. + +_L10: + // Flags set in _L10 call delay slot. + BNE _L4 +=-> COPY.0 1,R4 \ COPY.1 0,R5 + JR (R12) // Return to caller +=-> COPY.0 0,R6 \ COPY.1 0,R7 + +restOfCode: + +// Prologue + + // Register saves scheduled alongside special cases above. + ADD.0 FP,-20,FP \ STW R14,(FP)-4 + + // The following can be scheduled together. + // dividend in R[9:8] (from R[1:0]) + // divisor in R[7:6] (from R[3:2]) + // R14 := clzsi2 (dividend) + // R0 := clzsi2 (divisor) + JL (&__clzsi2) \ COPY.0 R0,R8 \ COPY.1 R1,R9 +=-> COPY.0 R2,R6 \ COPY.1 R3,R7 + COPY.0 R0,R14 \ JL (&__clzsi2) +=-> COPY.0 R6,R0 \ COPY.1 R7,R1 + + // R14 := R0 - R14 + SUB.0 R0,R14,R14 + + ADD.0 R14,1,R0 // R0 := R14 + 1 (HI) + + // R[11:10] = R[7,6] << R14 + SUB.0 15,R14,r15 + LSL.0 R6,R14,R11 \ BLT setupDivstepLoop +=-> SUB.0 0,R14,R4 \ COPY.1 0,R10 + + // Zero shift is a special case. Shifting by zero within a 16-bit + // source object is fine, but don't execute the OR of the right-shift + // into the final result. + LSL.0 R7,R14,R11 \ BEQ setupDivstepLoop +=-> LSL.0 R6,R14,R10 + + LSR.0 R6,R4,R4 + OR.0 R11,R4,R11 + +setupDivstepLoop: + + // R[5:4] := R[9:8] (SI) + COPY.0 R8,R4 \ COPY.1 R9,R5 + COPY.0 0,R6 \ COPY.1 R0,R8 + + // Store original value of loopCount for use after the loop. + // The Subtraction is handled in the tail of the loop iteration + // after this point. + SUB.0 R4,R10,R0 \ COPY.1 R8,R14 + + // workingResult in R4,5,6 + // temps in r0,1,2 and r7 + // alignedDivisor in R10,11 + // loopCount in r8 + // r3, r9 scratch, used for renaming. + +loopStart: + // R0 := R4 - zeroExtend (R10) - only need 33-bits (i.e., 48-bits) + SUBB.0 R5,R11,R1 \ LSR.1 R0,15,R3 + SUBB.0 R6,0,R2 \ LSR.1 R1,15,R6 + + // if (carry) goto shiftOnly + SUB.0 R8,1,R8 \ BNE shiftOnly +=-> LSR.0 R4,15,R7 \ LSL.1 R1,1,R9 + + OR.0 [LSL R0,1],1,R4 \ BNE loopStart +=-> SUB.0 R4,R10,R0 \ OR.1 R9,R3,R5 + + BRA loopEnd + +shiftOnly: + + OR.0 [LSL R5,1],R7,R5 \ BNE loopStart \ LSR.1 R5,15,R6 +=-> SUB.0 [LSL R4,1],R10,R0 \LSL.1 R4,1,R4 + +// End of loop +loopEnd: + + // Schedule the computation of the upper word after shifting + // alongside the decision over whether to branch, and the register + // restores. + // R10 is filled with a useful constant. + SUB.0 15,r14,r15 \ LDL (FP)4,R[13:12] + SUB.1 0,R14,R1 // Don't set flags! + LSL.0 R6,R1,R3 \ LDL (FP)-4,R[9:8] + + BLT remainderHasMoreThan16Bits \ LSR.0 R5,R14,R7 \ COPY.1 -1,R10 +=-> LSL.0 R5,R1,R2 \ OR.1 R7,R3,R3 + + LSR.0 R4,R14,R3 \ COPY.1 R3,R7 + BRA epilogue \ LSR.0 -1,R1,R0 \ COPY.1 0,R5 +=-> OR.0 R3,R2,R6 \ AND.1 R0,R4,R4 + +remainderHasMoreThan16Bits: + + LSL.0 R10,R14,R1 \ COPY.1 R3,R6 + XOR.0 R10,R1,R1 \ COPY.1 0,R7 + AND.0 R1,R5,R5 + +epilogue: + + JR (R12) \ LDW (FP)-4,R14 +=-> LDL (FP)-3,R[11:10] + +_picoMark_FUNCTION_END= + +// picoChip Function Epilogue : udivmodsi4 + +//============================================================================ +// All DWARF information between this marker, and the END OF DWARF +// marker should be included in the source file. Search for +// FUNCTION_STACK_SIZE_GOES_HERE and FUNCTION NAME GOES HERE, and +// provide the relevent information. Add markers called +// _picoMark_FUNCTION_BEGIN and _picoMark_FUNCTION_END around the +// function in question. +//============================================================================ + +//============================================================================ +// Frame information. +//============================================================================ + +.section .debug_frame +_picoMark_DebugFrame= + +// Common CIE header. +.unalignedInitLong _picoMark_CieEnd-_picoMark_CieBegin +_picoMark_CieBegin= +.unalignedInitLong 0xffffffff +.initByte 0x1 // CIE Version +.ascii 16#0# // CIE Augmentation +.uleb128 0x1 // CIE Code Alignment Factor +.sleb128 2 // CIE Data Alignment Factor +.initByte 0xc // CIE RA Column +.initByte 0xc // DW_CFA_def_cfa +.uleb128 0xd +.uleb128 0x0 +.align 2 +_picoMark_CieEnd= + +// FDE +_picoMark_LSFDE0I900821033007563= +.unalignedInitLong _picoMark_FdeEnd-_picoMark_FdeBegin +_picoMark_FdeBegin= +.unalignedInitLong _picoMark_DebugFrame // FDE CIE offset +.unalignedInitWord _picoMark_FUNCTION_BEGIN // FDE initial location +.unalignedInitWord _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x18 // <-- FUNCTION_STACK_SIZE_GOES_HERE +.initByte 0x4 // DW_CFA_advance_loc4 +.unalignedInitLong _picoMark_FUNCTION_END-_picoMark_FUNCTION_BEGIN +.initByte 0xe // DW_CFA_def_cfa_offset +.uleb128 0x0 +.align 2 +_picoMark_FdeEnd= + +//============================================================================ +// Abbrevation information. +//============================================================================ + +.section .debug_abbrev +_picoMark_ABBREVIATIONS= + +.section .debug_abbrev + .uleb128 0x1 // (abbrev code) + .uleb128 0x11 // (TAG: DW_TAG_compile_unit) + .initByte 0x1 // DW_children_yes + .uleb128 0x10 // (DW_AT_stmt_list) + .uleb128 0x6 // (DW_FORM_data4) + .uleb128 0x12 // (DW_AT_high_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x11 // (DW_AT_low_pc) + .uleb128 0x1 // (DW_FORM_addr) + .uleb128 0x25 // (DW_AT_producer) + .uleb128 0x8 // (DW_FORM_string) + .uleb128 0x13 // (DW_AT_language) + .uleb128 0x5 // (DW_FORM_data2) + .uleb128 0x3 // (DW_AT_name) + .uleb128 0x8 // (DW_FORM_string) +.initByte 0x0 +.initByte 0x0 + + .uleb128 0x2 ;# (abbrev code) + .uleb128 0x2e ;# (TAG: DW_TAG_subprogram) +.initByte 0x0 ;# DW_children_no + .uleb128 0x3 ;# (DW_AT_name) + .uleb128 0x8 ;# (DW_FORM_string) + .uleb128 0x11 ;# (DW_AT_low_pc) + .uleb128 0x1 ;# (DW_FORM_addr) + .uleb128 0x12 ;# (DW_AT_high_pc) + .uleb128 0x1 ;# (DW_FORM_addr) +.initByte 0x0 +.initByte 0x0 + +.initByte 0x0 + +//============================================================================ +// Line information. DwarfLib requires this to be present, but it can +// be empty. +//============================================================================ + +.section .debug_line +_picoMark_LINES= + +//============================================================================ +// Debug Information +//============================================================================ +.section .debug_info + +//Fixed header. +.unalignedInitLong _picoMark_DEBUG_INFO_END-_picoMark_DEBUG_INFO_BEGIN +_picoMark_DEBUG_INFO_BEGIN= +.unalignedInitWord 0x2 +.unalignedInitLong _picoMark_ABBREVIATIONS +.initByte 0x2 + +// Compile unit information. +.uleb128 0x1 // (DIE 0xb) DW_TAG_compile_unit) +.unalignedInitLong _picoMark_LINES +.unalignedInitWord _picoMark_FUNCTION_END +.unalignedInitWord _picoMark_FUNCTION_BEGIN +// Producer is `picoChip' +.ascii 16#70# 16#69# 16#63# 16#6f# 16#43# 16#68# 16#69# 16#70# 16#00# +.unalignedInitWord 0xcafe // ASM language +.ascii 16#0# // Name. DwarfLib expects this to be present. + +.uleb128 0x2 ;# (DIE DW_TAG_subprogram) + +// FUNCTION NAME GOES HERE. Use `echo name | od -t x1' to get the hex. Each hex +// digit is specified using the format 16#XX# +.ascii 16#5f# 16#75# 16#64# 16#69# 16#76# 16#6d# 16#6f# 16#64# 16#73# 16#69# 16#34# 16#0# // Function name `_udivmodsi4' +.unalignedInitWord _picoMark_FUNCTION_BEGIN // DW_AT_low_pc +.unalignedInitWord _picoMark_FUNCTION_END // DW_AT_high_pc + +.initByte 0x0 // end of compile unit children. + +_picoMark_DEBUG_INFO_END= + +//============================================================================ +// END OF DWARF +//============================================================================ +.section .endFile +// End of picoChip ASM file diff --git a/libgcc/config/rs6000/crtresfpr.S b/libgcc/config/rs6000/crtresfpr.S new file mode 100644 index 0000000..9fb228c --- /dev/null +++ b/libgcc/config/rs6000/crtresfpr.S @@ -0,0 +1,81 @@ +/* + * Special support for eabi and SVR4 + * + * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008, 2009 + * Free Software Foundation, Inc. + * Written By Michael Meissner + * 64-bit support written by David Edelsohn + * + * This file 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. + * + * This file 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/>. + */ + +/* Do any initializations needed for the eabi environment */ + + .section ".text" + #include "ppc-asm.h" + +/* On PowerPC64 Linux, these functions are provided by the linker. */ +#ifndef __powerpc64__ + +/* Routines for restoring floating point registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the floating point save area. */ + +CFI_STARTPROC +HIDDEN_FUNC(_restfpr_14) lfd 14,-144(11) /* restore fp registers */ +HIDDEN_FUNC(_restfpr_15) lfd 15,-136(11) +HIDDEN_FUNC(_restfpr_16) lfd 16,-128(11) +HIDDEN_FUNC(_restfpr_17) lfd 17,-120(11) +HIDDEN_FUNC(_restfpr_18) lfd 18,-112(11) +HIDDEN_FUNC(_restfpr_19) lfd 19,-104(11) +HIDDEN_FUNC(_restfpr_20) lfd 20,-96(11) +HIDDEN_FUNC(_restfpr_21) lfd 21,-88(11) +HIDDEN_FUNC(_restfpr_22) lfd 22,-80(11) +HIDDEN_FUNC(_restfpr_23) lfd 23,-72(11) +HIDDEN_FUNC(_restfpr_24) lfd 24,-64(11) +HIDDEN_FUNC(_restfpr_25) lfd 25,-56(11) +HIDDEN_FUNC(_restfpr_26) lfd 26,-48(11) +HIDDEN_FUNC(_restfpr_27) lfd 27,-40(11) +HIDDEN_FUNC(_restfpr_28) lfd 28,-32(11) +HIDDEN_FUNC(_restfpr_29) lfd 29,-24(11) +HIDDEN_FUNC(_restfpr_30) lfd 30,-16(11) +HIDDEN_FUNC(_restfpr_31) lfd 31,-8(11) + blr +FUNC_END(_restfpr_31) +FUNC_END(_restfpr_30) +FUNC_END(_restfpr_29) +FUNC_END(_restfpr_28) +FUNC_END(_restfpr_27) +FUNC_END(_restfpr_26) +FUNC_END(_restfpr_25) +FUNC_END(_restfpr_24) +FUNC_END(_restfpr_23) +FUNC_END(_restfpr_22) +FUNC_END(_restfpr_21) +FUNC_END(_restfpr_20) +FUNC_END(_restfpr_19) +FUNC_END(_restfpr_18) +FUNC_END(_restfpr_17) +FUNC_END(_restfpr_16) +FUNC_END(_restfpr_15) +FUNC_END(_restfpr_14) +CFI_ENDPROC + +#endif diff --git a/libgcc/config/rs6000/crtresgpr.S b/libgcc/config/rs6000/crtresgpr.S new file mode 100644 index 0000000..9f9cec9 --- /dev/null +++ b/libgcc/config/rs6000/crtresgpr.S @@ -0,0 +1,81 @@ +/* + * Special support for eabi and SVR4 + * + * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008, 2009 + * Free Software Foundation, Inc. + * Written By Michael Meissner + * 64-bit support written by David Edelsohn + * + * This file 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. + * + * This file 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/>. + */ + +/* Do any initializations needed for the eabi environment */ + + .section ".text" + #include "ppc-asm.h" + +/* On PowerPC64 Linux, these functions are provided by the linker. */ +#ifndef __powerpc64__ + +/* Routines for restoring integer registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the integer restore area. */ + +CFI_STARTPROC +HIDDEN_FUNC(_restgpr_14) lwz 14,-72(11) /* restore gp registers */ +HIDDEN_FUNC(_restgpr_15) lwz 15,-68(11) +HIDDEN_FUNC(_restgpr_16) lwz 16,-64(11) +HIDDEN_FUNC(_restgpr_17) lwz 17,-60(11) +HIDDEN_FUNC(_restgpr_18) lwz 18,-56(11) +HIDDEN_FUNC(_restgpr_19) lwz 19,-52(11) +HIDDEN_FUNC(_restgpr_20) lwz 20,-48(11) +HIDDEN_FUNC(_restgpr_21) lwz 21,-44(11) +HIDDEN_FUNC(_restgpr_22) lwz 22,-40(11) +HIDDEN_FUNC(_restgpr_23) lwz 23,-36(11) +HIDDEN_FUNC(_restgpr_24) lwz 24,-32(11) +HIDDEN_FUNC(_restgpr_25) lwz 25,-28(11) +HIDDEN_FUNC(_restgpr_26) lwz 26,-24(11) +HIDDEN_FUNC(_restgpr_27) lwz 27,-20(11) +HIDDEN_FUNC(_restgpr_28) lwz 28,-16(11) +HIDDEN_FUNC(_restgpr_29) lwz 29,-12(11) +HIDDEN_FUNC(_restgpr_30) lwz 30,-8(11) +HIDDEN_FUNC(_restgpr_31) lwz 31,-4(11) + blr +FUNC_END(_restgpr_31) +FUNC_END(_restgpr_30) +FUNC_END(_restgpr_29) +FUNC_END(_restgpr_28) +FUNC_END(_restgpr_27) +FUNC_END(_restgpr_26) +FUNC_END(_restgpr_25) +FUNC_END(_restgpr_24) +FUNC_END(_restgpr_23) +FUNC_END(_restgpr_22) +FUNC_END(_restgpr_21) +FUNC_END(_restgpr_20) +FUNC_END(_restgpr_19) +FUNC_END(_restgpr_18) +FUNC_END(_restgpr_17) +FUNC_END(_restgpr_16) +FUNC_END(_restgpr_15) +FUNC_END(_restgpr_14) +CFI_ENDPROC + +#endif diff --git a/libgcc/config/rs6000/crtresxfpr.S b/libgcc/config/rs6000/crtresxfpr.S new file mode 100644 index 0000000..633f2db --- /dev/null +++ b/libgcc/config/rs6000/crtresxfpr.S @@ -0,0 +1,126 @@ +/* + * Special support for eabi and SVR4 + * + * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008, 2009 + * Free Software Foundation, Inc. + * Written By Michael Meissner + * 64-bit support written by David Edelsohn + * + * This file 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. + * + * This file 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/>. + */ + +/* Do any initializations needed for the eabi environment */ + + .section ".text" + #include "ppc-asm.h" + +/* On PowerPC64 Linux, these functions are provided by the linker. */ +#ifndef __powerpc64__ + +/* Routines for restoring floating point registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the floating point save area. */ +/* In addition to restoring the fp registers, it will return to the caller's */ +/* caller */ + +CFI_STARTPROC +CFI_DEF_CFA_REGISTER (11) +CFI_OFFSET (65, 4) +CFI_OFFSET (46, -144) +CFI_OFFSET (47, -136) +CFI_OFFSET (48, -128) +CFI_OFFSET (49, -120) +CFI_OFFSET (50, -112) +CFI_OFFSET (51, -104) +CFI_OFFSET (52, -96) +CFI_OFFSET (53, -88) +CFI_OFFSET (54, -80) +CFI_OFFSET (55, -72) +CFI_OFFSET (56, -64) +CFI_OFFSET (57, -56) +CFI_OFFSET (58, -48) +CFI_OFFSET (59, -40) +CFI_OFFSET (60, -32) +CFI_OFFSET (61, -24) +CFI_OFFSET (62, -16) +CFI_OFFSET (63, -8) +HIDDEN_FUNC(_restfpr_14_x) lfd 14,-144(11) /* restore fp registers */ +CFI_RESTORE (46) +HIDDEN_FUNC(_restfpr_15_x) lfd 15,-136(11) +CFI_RESTORE (47) +HIDDEN_FUNC(_restfpr_16_x) lfd 16,-128(11) +CFI_RESTORE (48) +HIDDEN_FUNC(_restfpr_17_x) lfd 17,-120(11) +CFI_RESTORE (49) +HIDDEN_FUNC(_restfpr_18_x) lfd 18,-112(11) +CFI_RESTORE (50) +HIDDEN_FUNC(_restfpr_19_x) lfd 19,-104(11) +CFI_RESTORE (51) +HIDDEN_FUNC(_restfpr_20_x) lfd 20,-96(11) +CFI_RESTORE (52) +HIDDEN_FUNC(_restfpr_21_x) lfd 21,-88(11) +CFI_RESTORE (53) +HIDDEN_FUNC(_restfpr_22_x) lfd 22,-80(11) +CFI_RESTORE (54) +HIDDEN_FUNC(_restfpr_23_x) lfd 23,-72(11) +CFI_RESTORE (55) +HIDDEN_FUNC(_restfpr_24_x) lfd 24,-64(11) +CFI_RESTORE (56) +HIDDEN_FUNC(_restfpr_25_x) lfd 25,-56(11) +CFI_RESTORE (57) +HIDDEN_FUNC(_restfpr_26_x) lfd 26,-48(11) +CFI_RESTORE (58) +HIDDEN_FUNC(_restfpr_27_x) lfd 27,-40(11) +CFI_RESTORE (59) +HIDDEN_FUNC(_restfpr_28_x) lfd 28,-32(11) +CFI_RESTORE (60) +HIDDEN_FUNC(_restfpr_29_x) lfd 29,-24(11) +CFI_RESTORE (61) +HIDDEN_FUNC(_restfpr_30_x) lfd 30,-16(11) +CFI_RESTORE (62) +HIDDEN_FUNC(_restfpr_31_x) lwz 0,4(11) + lfd 31,-8(11) +CFI_RESTORE (63) + mtlr 0 +CFI_RESTORE (65) + mr 1,11 +CFI_DEF_CFA_REGISTER (1) + blr +FUNC_END(_restfpr_31_x) +FUNC_END(_restfpr_30_x) +FUNC_END(_restfpr_29_x) +FUNC_END(_restfpr_28_x) +FUNC_END(_restfpr_27_x) +FUNC_END(_restfpr_26_x) +FUNC_END(_restfpr_25_x) +FUNC_END(_restfpr_24_x) +FUNC_END(_restfpr_23_x) +FUNC_END(_restfpr_22_x) +FUNC_END(_restfpr_21_x) +FUNC_END(_restfpr_20_x) +FUNC_END(_restfpr_19_x) +FUNC_END(_restfpr_18_x) +FUNC_END(_restfpr_17_x) +FUNC_END(_restfpr_16_x) +FUNC_END(_restfpr_15_x) +FUNC_END(_restfpr_14_x) +CFI_ENDPROC + +#endif diff --git a/libgcc/config/rs6000/crtresxgpr.S b/libgcc/config/rs6000/crtresxgpr.S new file mode 100644 index 0000000..451b2b6 --- /dev/null +++ b/libgcc/config/rs6000/crtresxgpr.S @@ -0,0 +1,124 @@ +/* + * Special support for eabi and SVR4 + * + * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008, 2009 + * Free Software Foundation, Inc. + * Written By Michael Meissner + * 64-bit support written by David Edelsohn + * + * This file 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. + * + * This file 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/>. + */ + +/* Do any initializations needed for the eabi environment */ + + .section ".text" + #include "ppc-asm.h" + +/* On PowerPC64 Linux, these functions are provided by the linker. */ +#ifndef __powerpc64__ + +/* Routines for restoring integer registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the integer restore area. */ + +CFI_STARTPROC +CFI_DEF_CFA_REGISTER (11) +CFI_OFFSET (65, 4) +CFI_OFFSET (14, -72) +CFI_OFFSET (15, -68) +CFI_OFFSET (16, -64) +CFI_OFFSET (17, -60) +CFI_OFFSET (18, -56) +CFI_OFFSET (19, -52) +CFI_OFFSET (20, -48) +CFI_OFFSET (21, -44) +CFI_OFFSET (22, -40) +CFI_OFFSET (23, -36) +CFI_OFFSET (24, -32) +CFI_OFFSET (25, -28) +CFI_OFFSET (26, -24) +CFI_OFFSET (27, -20) +CFI_OFFSET (28, -16) +CFI_OFFSET (29, -12) +CFI_OFFSET (30, -8) +CFI_OFFSET (31, -4) +HIDDEN_FUNC(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */ +CFI_RESTORE (14) +HIDDEN_FUNC(_restgpr_15_x) lwz 15,-68(11) +CFI_RESTORE (15) +HIDDEN_FUNC(_restgpr_16_x) lwz 16,-64(11) +CFI_RESTORE (16) +HIDDEN_FUNC(_restgpr_17_x) lwz 17,-60(11) +CFI_RESTORE (17) +HIDDEN_FUNC(_restgpr_18_x) lwz 18,-56(11) +CFI_RESTORE (18) +HIDDEN_FUNC(_restgpr_19_x) lwz 19,-52(11) +CFI_RESTORE (19) +HIDDEN_FUNC(_restgpr_20_x) lwz 20,-48(11) +CFI_RESTORE (20) +HIDDEN_FUNC(_restgpr_21_x) lwz 21,-44(11) +CFI_RESTORE (21) +HIDDEN_FUNC(_restgpr_22_x) lwz 22,-40(11) +CFI_RESTORE (22) +HIDDEN_FUNC(_restgpr_23_x) lwz 23,-36(11) +CFI_RESTORE (23) +HIDDEN_FUNC(_restgpr_24_x) lwz 24,-32(11) +CFI_RESTORE (24) +HIDDEN_FUNC(_restgpr_25_x) lwz 25,-28(11) +CFI_RESTORE (25) +HIDDEN_FUNC(_restgpr_26_x) lwz 26,-24(11) +CFI_RESTORE (26) +HIDDEN_FUNC(_restgpr_27_x) lwz 27,-20(11) +CFI_RESTORE (27) +HIDDEN_FUNC(_restgpr_28_x) lwz 28,-16(11) +CFI_RESTORE (28) +HIDDEN_FUNC(_restgpr_29_x) lwz 29,-12(11) +CFI_RESTORE (29) +HIDDEN_FUNC(_restgpr_30_x) lwz 30,-8(11) +CFI_RESTORE (30) +HIDDEN_FUNC(_restgpr_31_x) lwz 0,4(11) + lwz 31,-4(11) +CFI_RESTORE (31) + mtlr 0 +CFI_RESTORE (65) + mr 1,11 +CFI_DEF_CFA_REGISTER (1) + blr +FUNC_END(_restgpr_31_x) +FUNC_END(_restgpr_30_x) +FUNC_END(_restgpr_29_x) +FUNC_END(_restgpr_28_x) +FUNC_END(_restgpr_27_x) +FUNC_END(_restgpr_26_x) +FUNC_END(_restgpr_25_x) +FUNC_END(_restgpr_24_x) +FUNC_END(_restgpr_23_x) +FUNC_END(_restgpr_22_x) +FUNC_END(_restgpr_21_x) +FUNC_END(_restgpr_20_x) +FUNC_END(_restgpr_19_x) +FUNC_END(_restgpr_18_x) +FUNC_END(_restgpr_17_x) +FUNC_END(_restgpr_16_x) +FUNC_END(_restgpr_15_x) +FUNC_END(_restgpr_14_x) +CFI_ENDPROC + +#endif diff --git a/libgcc/config/rs6000/crtsavfpr.S b/libgcc/config/rs6000/crtsavfpr.S new file mode 100644 index 0000000..3cdb250 --- /dev/null +++ b/libgcc/config/rs6000/crtsavfpr.S @@ -0,0 +1,81 @@ +/* + * Special support for eabi and SVR4 + * + * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008, 2009 + * Free Software Foundation, Inc. + * Written By Michael Meissner + * 64-bit support written by David Edelsohn + * + * This file 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. + * + * This file 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/>. + */ + +/* Do any initializations needed for the eabi environment */ + + .section ".text" + #include "ppc-asm.h" + +/* On PowerPC64 Linux, these functions are provided by the linker. */ +#ifndef __powerpc64__ + +/* Routines for saving floating point registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the floating point save area. */ + +CFI_STARTPROC +HIDDEN_FUNC(_savefpr_14) stfd 14,-144(11) /* save fp registers */ +HIDDEN_FUNC(_savefpr_15) stfd 15,-136(11) +HIDDEN_FUNC(_savefpr_16) stfd 16,-128(11) +HIDDEN_FUNC(_savefpr_17) stfd 17,-120(11) +HIDDEN_FUNC(_savefpr_18) stfd 18,-112(11) +HIDDEN_FUNC(_savefpr_19) stfd 19,-104(11) +HIDDEN_FUNC(_savefpr_20) stfd 20,-96(11) +HIDDEN_FUNC(_savefpr_21) stfd 21,-88(11) +HIDDEN_FUNC(_savefpr_22) stfd 22,-80(11) +HIDDEN_FUNC(_savefpr_23) stfd 23,-72(11) +HIDDEN_FUNC(_savefpr_24) stfd 24,-64(11) +HIDDEN_FUNC(_savefpr_25) stfd 25,-56(11) +HIDDEN_FUNC(_savefpr_26) stfd 26,-48(11) +HIDDEN_FUNC(_savefpr_27) stfd 27,-40(11) +HIDDEN_FUNC(_savefpr_28) stfd 28,-32(11) +HIDDEN_FUNC(_savefpr_29) stfd 29,-24(11) +HIDDEN_FUNC(_savefpr_30) stfd 30,-16(11) +HIDDEN_FUNC(_savefpr_31) stfd 31,-8(11) + blr +FUNC_END(_savefpr_31) +FUNC_END(_savefpr_30) +FUNC_END(_savefpr_29) +FUNC_END(_savefpr_28) +FUNC_END(_savefpr_27) +FUNC_END(_savefpr_26) +FUNC_END(_savefpr_25) +FUNC_END(_savefpr_24) +FUNC_END(_savefpr_23) +FUNC_END(_savefpr_22) +FUNC_END(_savefpr_21) +FUNC_END(_savefpr_20) +FUNC_END(_savefpr_19) +FUNC_END(_savefpr_18) +FUNC_END(_savefpr_17) +FUNC_END(_savefpr_16) +FUNC_END(_savefpr_15) +FUNC_END(_savefpr_14) +CFI_ENDPROC + +#endif diff --git a/libgcc/config/rs6000/crtsavgpr.S b/libgcc/config/rs6000/crtsavgpr.S new file mode 100644 index 0000000..6d473963 --- /dev/null +++ b/libgcc/config/rs6000/crtsavgpr.S @@ -0,0 +1,81 @@ +/* + * Special support for eabi and SVR4 + * + * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008, 2009 + * Free Software Foundation, Inc. + * Written By Michael Meissner + * 64-bit support written by David Edelsohn + * + * This file 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. + * + * This file 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/>. + */ + +/* Do any initializations needed for the eabi environment */ + + .section ".text" + #include "ppc-asm.h" + +/* On PowerPC64 Linux, these functions are provided by the linker. */ +#ifndef __powerpc64__ + +/* Routines for saving integer registers, called by the compiler. */ +/* Called with r11 pointing to the stack header word of the caller of the */ +/* function, just beyond the end of the integer save area. */ + +CFI_STARTPROC +HIDDEN_FUNC(_savegpr_14) stw 14,-72(11) /* save gp registers */ +HIDDEN_FUNC(_savegpr_15) stw 15,-68(11) +HIDDEN_FUNC(_savegpr_16) stw 16,-64(11) +HIDDEN_FUNC(_savegpr_17) stw 17,-60(11) +HIDDEN_FUNC(_savegpr_18) stw 18,-56(11) +HIDDEN_FUNC(_savegpr_19) stw 19,-52(11) +HIDDEN_FUNC(_savegpr_20) stw 20,-48(11) +HIDDEN_FUNC(_savegpr_21) stw 21,-44(11) +HIDDEN_FUNC(_savegpr_22) stw 22,-40(11) +HIDDEN_FUNC(_savegpr_23) stw 23,-36(11) +HIDDEN_FUNC(_savegpr_24) stw 24,-32(11) +HIDDEN_FUNC(_savegpr_25) stw 25,-28(11) +HIDDEN_FUNC(_savegpr_26) stw 26,-24(11) +HIDDEN_FUNC(_savegpr_27) stw 27,-20(11) +HIDDEN_FUNC(_savegpr_28) stw 28,-16(11) +HIDDEN_FUNC(_savegpr_29) stw 29,-12(11) +HIDDEN_FUNC(_savegpr_30) stw 30,-8(11) +HIDDEN_FUNC(_savegpr_31) stw 31,-4(11) + blr +FUNC_END(_savegpr_31) +FUNC_END(_savegpr_30) +FUNC_END(_savegpr_29) +FUNC_END(_savegpr_28) +FUNC_END(_savegpr_27) +FUNC_END(_savegpr_26) +FUNC_END(_savegpr_25) +FUNC_END(_savegpr_24) +FUNC_END(_savegpr_23) +FUNC_END(_savegpr_22) +FUNC_END(_savegpr_21) +FUNC_END(_savegpr_20) +FUNC_END(_savegpr_19) +FUNC_END(_savegpr_18) +FUNC_END(_savegpr_17) +FUNC_END(_savegpr_16) +FUNC_END(_savegpr_15) +FUNC_END(_savegpr_14) +CFI_ENDPROC + +#endif diff --git a/libgcc/config/rs6000/darwin-asm.h b/libgcc/config/rs6000/darwin-asm.h new file mode 100644 index 0000000..837b7a3 --- /dev/null +++ b/libgcc/config/rs6000/darwin-asm.h @@ -0,0 +1,51 @@ +/* Macro definitions to used to support 32/64-bit code in Darwin's + * assembly files. + * + * Copyright (C) 2004, 2009 Free Software Foundation, Inc. + * + * This file 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. + * + * This file 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/>. + */ + +/* These are donated from /usr/include/architecture/ppc . */ + +#if defined(__ppc64__) +#define MODE_CHOICE(x, y) y +#else +#define MODE_CHOICE(x, y) x +#endif + +#define cmpg MODE_CHOICE(cmpw, cmpd) +#define lg MODE_CHOICE(lwz, ld) +#define stg MODE_CHOICE(stw, std) +#define lgx MODE_CHOICE(lwzx, ldx) +#define stgx MODE_CHOICE(stwx, stdx) +#define lgu MODE_CHOICE(lwzu, ldu) +#define stgu MODE_CHOICE(stwu, stdu) +#define lgux MODE_CHOICE(lwzux, ldux) +#define stgux MODE_CHOICE(stwux, stdux) +#define lgwa MODE_CHOICE(lwz, lwa) + +#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ + +#define GPR_BYTES MODE_CHOICE(4,8) /* size of a GPR in bytes */ +#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ + +#define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* position of saved + LR in frame */ diff --git a/libgcc/config/rs6000/darwin-fpsave.S b/libgcc/config/rs6000/darwin-fpsave.S new file mode 100644 index 0000000..47fdc92 --- /dev/null +++ b/libgcc/config/rs6000/darwin-fpsave.S @@ -0,0 +1,92 @@ +/* This file contains the floating-point save and restore routines. + * + * Copyright (C) 2004, 2009 Free Software Foundation, Inc. + * + * This file 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. + * + * This file 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/>. + */ + +/* THE SAVE AND RESTORE ROUTINES CAN HAVE ONLY ONE GLOBALLY VISIBLE + ENTRY POINT - callers have to jump to "saveFP+60" to save f29..f31, + for example. For FP reg saves/restores, it takes one instruction + (4 bytes) to do the operation; for Vector regs, 2 instructions are + required (8 bytes.) + + MORAL: DO NOT MESS AROUND WITH THESE FUNCTIONS! */ + +#include "darwin-asm.h" + +.text + .align 2 + +/* saveFP saves R0 -- assumed to be the callers LR -- to 8/16(R1). */ + +.private_extern saveFP +saveFP: + stfd f14,-144(r1) + stfd f15,-136(r1) + stfd f16,-128(r1) + stfd f17,-120(r1) + stfd f18,-112(r1) + stfd f19,-104(r1) + stfd f20,-96(r1) + stfd f21,-88(r1) + stfd f22,-80(r1) + stfd f23,-72(r1) + stfd f24,-64(r1) + stfd f25,-56(r1) + stfd f26,-48(r1) + stfd f27,-40(r1) + stfd f28,-32(r1) + stfd f29,-24(r1) + stfd f30,-16(r1) + stfd f31,-8(r1) + stg r0,SAVED_LR_OFFSET(r1) + blr + +/* restFP restores the caller`s LR from 8/16(R1). Note that the code for + this starts at the offset of F30 restoration, so calling this + routine in an attempt to restore only F31 WILL NOT WORK (it would + be a stupid thing to do, anyway.) */ + +.private_extern restFP +restFP: + lfd f14,-144(r1) + lfd f15,-136(r1) + lfd f16,-128(r1) + lfd f17,-120(r1) + lfd f18,-112(r1) + lfd f19,-104(r1) + lfd f20,-96(r1) + lfd f21,-88(r1) + lfd f22,-80(r1) + lfd f23,-72(r1) + lfd f24,-64(r1) + lfd f25,-56(r1) + lfd f26,-48(r1) + lfd f27,-40(r1) + lfd f28,-32(r1) + lfd f29,-24(r1) + /* <OFFSET OF F30 RESTORE> restore callers LR */ + lg r0,SAVED_LR_OFFSET(r1) + lfd f30,-16(r1) + /* and prepare for return to caller */ + mtlr r0 + lfd f31,-8(r1) + blr diff --git a/libgcc/config/rs6000/darwin-gpsave.S b/libgcc/config/rs6000/darwin-gpsave.S new file mode 100644 index 0000000..d3c3b91 --- /dev/null +++ b/libgcc/config/rs6000/darwin-gpsave.S @@ -0,0 +1,118 @@ +/* This file contains the GPR save and restore routines for Darwin. + * + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * This file 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. + * + * This file 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/>. + */ + +/* Contributed by Iain Sandoe <iains@gcc.gnu.org> */ + +/* Like their FP and VEC counterparts, these routines have only one externally + visible entry point. Calls have to be constructed as offsets from this. + (I.E. callers have to jump to "saveGPR+((x-13)*4" to save registers x..31). + + Each save/load instruction is 4 bytes long (for both m32 and m64 builds). + + The save/restores here are done w.r.t r11. + + restGPRx restores the link reg from the stack and returns to the saved + address. + + */ + +#include "darwin-asm.h" + + .text + .align 2 + + .private_extern saveGPR +saveGPR: + stg r13,(-19 * GPR_BYTES)(r11) + stg r14,(-18 * GPR_BYTES)(r11) + stg r15,(-17 * GPR_BYTES)(r11) + stg r16,(-16 * GPR_BYTES)(r11) + stg r17,(-15 * GPR_BYTES)(r11) + stg r18,(-14 * GPR_BYTES)(r11) + stg r19,(-13 * GPR_BYTES)(r11) + stg r20,(-12 * GPR_BYTES)(r11) + stg r21,(-11 * GPR_BYTES)(r11) + stg r22,(-10 * GPR_BYTES)(r11) + stg r23,( -9 * GPR_BYTES)(r11) + stg r24,( -8 * GPR_BYTES)(r11) + stg r25,( -7 * GPR_BYTES)(r11) + stg r26,( -6 * GPR_BYTES)(r11) + stg r27,( -5 * GPR_BYTES)(r11) + stg r28,( -4 * GPR_BYTES)(r11) + stg r29,( -3 * GPR_BYTES)(r11) + stg r30,( -2 * GPR_BYTES)(r11) + stg r31,( -1 * GPR_BYTES)(r11) + blr + +/* */ + + .private_extern restGPR +restGPR: + lg r13,(-19 * GPR_BYTES)(r11) + lg r14,(-18 * GPR_BYTES)(r11) + lg r15,(-17 * GPR_BYTES)(r11) + lg r16,(-16 * GPR_BYTES)(r11) + lg r17,(-15 * GPR_BYTES)(r11) + lg r18,(-14 * GPR_BYTES)(r11) + lg r19,(-13 * GPR_BYTES)(r11) + lg r20,(-12 * GPR_BYTES)(r11) + lg r21,(-11 * GPR_BYTES)(r11) + lg r22,(-10 * GPR_BYTES)(r11) + lg r23,( -9 * GPR_BYTES)(r11) + lg r24,( -8 * GPR_BYTES)(r11) + lg r25,( -7 * GPR_BYTES)(r11) + lg r26,( -6 * GPR_BYTES)(r11) + lg r27,( -5 * GPR_BYTES)(r11) + lg r28,( -4 * GPR_BYTES)(r11) + lg r29,( -3 * GPR_BYTES)(r11) + lg r30,( -2 * GPR_BYTES)(r11) + lg r31,( -1 * GPR_BYTES)(r11) + blr + + .private_extern restGPRx +restGPRx: + lg r13,(-19 * GPR_BYTES)(r11) + lg r14,(-18 * GPR_BYTES)(r11) + lg r15,(-17 * GPR_BYTES)(r11) + lg r16,(-16 * GPR_BYTES)(r11) + lg r17,(-15 * GPR_BYTES)(r11) + lg r18,(-14 * GPR_BYTES)(r11) + lg r19,(-13 * GPR_BYTES)(r11) + lg r20,(-12 * GPR_BYTES)(r11) + lg r21,(-11 * GPR_BYTES)(r11) + lg r22,(-10 * GPR_BYTES)(r11) + lg r23,( -9 * GPR_BYTES)(r11) + lg r24,( -8 * GPR_BYTES)(r11) + lg r25,( -7 * GPR_BYTES)(r11) + lg r26,( -6 * GPR_BYTES)(r11) + lg r27,( -5 * GPR_BYTES)(r11) + lg r28,( -4 * GPR_BYTES)(r11) + lg r29,( -3 * GPR_BYTES)(r11) + /* Like the FP restore, we start from the offset for r30 + thus a restore of only r31 is not going to work. */ + lg r0,SAVED_LR_OFFSET(r1) + lg r30,( -2 * GPR_BYTES)(r11) + mtlr r0 + lg r31,( -1 * GPR_BYTES)(r11) + blr diff --git a/libgcc/config/rs6000/darwin-tramp.S b/libgcc/config/rs6000/darwin-tramp.S new file mode 100644 index 0000000..5188c98 --- /dev/null +++ b/libgcc/config/rs6000/darwin-tramp.S @@ -0,0 +1,125 @@ +/* Special support for trampolines + * + * Copyright (C) 1996, 1997, 2000, 2004, 2005, 2009 Free Software Foundation, Inc. + * Written By Michael Meissner + * + * This file 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. + * + * This file 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 "darwin-asm.h" + +/* Set up trampolines. */ + +.text + .align LOG2_GPR_BYTES +Ltrampoline_initial: + mflr r0 + bl 1f +Lfunc = .-Ltrampoline_initial + .g_long 0 /* will be replaced with function address */ +Lchain = .-Ltrampoline_initial + .g_long 0 /* will be replaced with static chain */ +1: mflr r11 + lg r12,0(r11) /* function address */ + mtlr r0 + mtctr r12 + lg r11,GPR_BYTES(r11) /* static chain */ + bctr + +trampoline_size = .-Ltrampoline_initial + +/* R3 = stack address to store trampoline */ +/* R4 = length of trampoline area */ +/* R5 = function address */ +/* R6 = static chain */ + + .globl ___trampoline_setup +___trampoline_setup: + mflr r0 /* save return address */ + bcl 20,31,LCF0 /* load up __trampoline_initial into r7 */ +LCF0: + mflr r11 + addis r7,r11,ha16(LTRAMP-LCF0) + lg r7,lo16(LTRAMP-LCF0)(r7) + subi r7,r7,4 + li r8,trampoline_size /* verify trampoline big enough */ + cmpg cr1,r8,r4 + srwi r4,r4,2 /* # words to move (insns always 4-byte) */ + addi r9,r3,-4 /* adjust pointer for lgu */ + mtctr r4 + blt cr1,Labort + + mtlr r0 + + /* Copy the instructions to the stack */ +Lmove: + lwzu r10,4(r7) + stwu r10,4(r9) + bdnz Lmove + + /* Store correct function and static chain */ + stg r5,Lfunc(r3) + stg r6,Lchain(r3) + + /* Now flush both caches */ + mtctr r4 +Lcache: + icbi 0,r3 + dcbf 0,r3 + addi r3,r3,4 + bdnz Lcache + + /* Ensure cache-flushing has finished. */ + sync + isync + + /* Make stack writeable. */ + b ___enable_execute_stack + +Labort: +#ifdef __DYNAMIC__ + bl L_abort$stub +.data +.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align 2 +L_abort$stub: + .indirect_symbol _abort + mflr r0 + bcl 20,31,L0$_abort +L0$_abort: + mflr r11 + addis r11,r11,ha16(L_abort$lazy_ptr-L0$_abort) + mtlr r0 + lgu r12,lo16(L_abort$lazy_ptr-L0$_abort)(r11) + mtctr r12 + bctr +.data +.lazy_symbol_pointer +L_abort$lazy_ptr: + .indirect_symbol _abort + .g_long dyld_stub_binding_helper +#else + bl _abort +#endif +.data + .align LOG2_GPR_BYTES +LTRAMP: + .g_long Ltrampoline_initial + diff --git a/libgcc/config/rs6000/darwin-vecsave.S b/libgcc/config/rs6000/darwin-vecsave.S new file mode 100644 index 0000000..0a46be20 --- /dev/null +++ b/libgcc/config/rs6000/darwin-vecsave.S @@ -0,0 +1,155 @@ +/* This file contains the vector save and restore routines. + * + * Copyright (C) 2004, 2009 Free Software Foundation, Inc. + * + * This file 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. + * + * This file 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/>. + */ + +/* Vector save/restore routines for Darwin. Note that each vector + save/restore requires 2 instructions (8 bytes.) + + THE SAVE AND RESTORE ROUTINES CAN HAVE ONLY ONE GLOBALLY VISIBLE + ENTRY POINT - callers have to jump to "saveFP+60" to save f29..f31, + for example. For FP reg saves/restores, it takes one instruction + (4 bytes) to do the operation; for Vector regs, 2 instructions are + required (8 bytes.). */ + + .machine ppc7400 +.text + .align 2 + +.private_extern saveVEC +saveVEC: + li r11,-192 + stvx v20,r11,r0 + li r11,-176 + stvx v21,r11,r0 + li r11,-160 + stvx v22,r11,r0 + li r11,-144 + stvx v23,r11,r0 + li r11,-128 + stvx v24,r11,r0 + li r11,-112 + stvx v25,r11,r0 + li r11,-96 + stvx v26,r11,r0 + li r11,-80 + stvx v27,r11,r0 + li r11,-64 + stvx v28,r11,r0 + li r11,-48 + stvx v29,r11,r0 + li r11,-32 + stvx v30,r11,r0 + li r11,-16 + stvx v31,r11,r0 + blr + +.private_extern restVEC +restVEC: + li r11,-192 + lvx v20,r11,r0 + li r11,-176 + lvx v21,r11,r0 + li r11,-160 + lvx v22,r11,r0 + li r11,-144 + lvx v23,r11,r0 + li r11,-128 + lvx v24,r11,r0 + li r11,-112 + lvx v25,r11,r0 + li r11,-96 + lvx v26,r11,r0 + li r11,-80 + lvx v27,r11,r0 + li r11,-64 + lvx v28,r11,r0 + li r11,-48 + lvx v29,r11,r0 + li r11,-32 + lvx v30,r11,r0 + li r11,-16 + lvx v31,r11,r0 + blr + +/* saveVEC_vr11 -- as saveVEC but VRsave is returned in R11. */ + +.private_extern saveVEC_vr11 +saveVEC_vr11: + li r11,-192 + stvx v20,r11,r0 + li r11,-176 + stvx v21,r11,r0 + li r11,-160 + stvx v22,r11,r0 + li r11,-144 + stvx v23,r11,r0 + li r11,-128 + stvx v24,r11,r0 + li r11,-112 + stvx v25,r11,r0 + li r11,-96 + stvx v26,r11,r0 + li r11,-80 + stvx v27,r11,r0 + li r11,-64 + stvx v28,r11,r0 + li r11,-48 + stvx v29,r11,r0 + li r11,-32 + stvx v30,r11,r0 + li r11,-16 + stvx v31,r11,r0 + mfspr r11,VRsave + blr + +/* As restVec, but the original VRsave value passed in R10. */ + +.private_extern restVEC_vr10 +restVEC_vr10: + li r11,-192 + lvx v20,r11,r0 + li r11,-176 + lvx v21,r11,r0 + li r11,-160 + lvx v22,r11,r0 + li r11,-144 + lvx v23,r11,r0 + li r11,-128 + lvx v24,r11,r0 + li r11,-112 + lvx v25,r11,r0 + li r11,-96 + lvx v26,r11,r0 + li r11,-80 + lvx v27,r11,r0 + li r11,-64 + lvx v28,r11,r0 + li r11,-48 + lvx v29,r11,r0 + li r11,-32 + lvx v30,r11,r0 + li r11,-16 + lvx v31,r11,r0 + /* restore VRsave from R10. */ + mtspr VRsave,r10 + blr diff --git a/libgcc/config/rs6000/darwin-world.S b/libgcc/config/rs6000/darwin-world.S new file mode 100644 index 0000000..c0b1bf1 --- /dev/null +++ b/libgcc/config/rs6000/darwin-world.S @@ -0,0 +1,259 @@ +/* This file contains the exception-handling save_world and + * restore_world routines, which need to do a run-time check to see if + * they should save and restore the vector registers. + * + * Copyright (C) 2004, 2009 Free Software Foundation, Inc. + * + * This file 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. + * + * This file 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/>. + */ + + .machine ppc7400 +.data + .align 2 + +#ifdef __DYNAMIC__ + +.non_lazy_symbol_pointer +L_has_vec$non_lazy_ptr: + .indirect_symbol __cpu_has_altivec +#ifdef __ppc64__ + .quad 0 +#else + .long 0 +#endif + +#else + +/* For static, "pretend" we have a non-lazy-pointer. */ + +L_has_vec$non_lazy_ptr: + .long __cpu_has_altivec + +#endif + + +.text + .align 2 + +/* save_world and rest_world save/restore F14-F31 and possibly V20-V31 + (assuming you have a CPU with vector registers; we use a global var + provided by the System Framework to determine this.) + + SAVE_WORLD takes R0 (the caller`s caller`s return address) and R11 + (the stack frame size) as parameters. It returns VRsave in R0 if + we`re on a CPU with vector regs. + + With gcc3, we now need to save and restore CR as well, since gcc3's + scheduled prologs can cause comparisons to be moved before calls to + save_world! + + USES: R0 R11 R12 */ + +.private_extern save_world +save_world: + stw r0,8(r1) + mflr r0 + bcl 20,31,Ls$pb +Ls$pb: mflr r12 + addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Ls$pb) + lwz r12,lo16(L_has_vec$non_lazy_ptr-Ls$pb)(r12) + mtlr r0 + lwz r12,0(r12) + /* grab CR */ + mfcr r0 + /* test HAS_VEC */ + cmpwi r12,0 + stfd f14,-144(r1) + stfd f15,-136(r1) + stfd f16,-128(r1) + stfd f17,-120(r1) + stfd f18,-112(r1) + stfd f19,-104(r1) + stfd f20,-96(r1) + stfd f21,-88(r1) + stfd f22,-80(r1) + stfd f23,-72(r1) + stfd f24,-64(r1) + stfd f25,-56(r1) + stfd f26,-48(r1) + stfd f27,-40(r1) + stfd f28,-32(r1) + stfd f29,-24(r1) + stfd f30,-16(r1) + stfd f31,-8(r1) + stmw r13,-220(r1) + /* stash CR */ + stw r0,4(r1) + /* set R12 pointing at Vector Reg save area */ + addi r12,r1,-224 + /* allocate stack frame */ + stwux r1,r1,r11 + /* ...but return if HAS_VEC is zero */ + bne+ L$saveVMX + /* Not forgetting to restore CR. */ + mtcr r0 + blr + +L$saveVMX: + /* We're saving Vector regs too. */ + /* Restore CR from R0. No More Branches! */ + mtcr r0 + + /* We should really use VRSAVE to figure out which vector regs + we actually need to save and restore. Some other time :-/ */ + + li r11,-192 + stvx v20,r11,r12 + li r11,-176 + stvx v21,r11,r12 + li r11,-160 + stvx v22,r11,r12 + li r11,-144 + stvx v23,r11,r12 + li r11,-128 + stvx v24,r11,r12 + li r11,-112 + stvx v25,r11,r12 + li r11,-96 + stvx v26,r11,r12 + li r11,-80 + stvx v27,r11,r12 + li r11,-64 + stvx v28,r11,r12 + li r11,-48 + stvx v29,r11,r12 + li r11,-32 + stvx v30,r11,r12 + mfspr r0,VRsave + li r11,-16 + stvx v31,r11,r12 + /* VRsave lives at -224(R1) */ + stw r0,0(r12) + blr + + +/* eh_rest_world_r10 is jumped to, not called, so no need to worry about LR. + R10 is the C++ EH stack adjust parameter, we return to the caller`s caller. + + USES: R0 R10 R11 R12 and R7 R8 + RETURNS: C++ EH Data registers (R3 - R6.) + + We now set up R7/R8 and jump to rest_world_eh_r7r8. + + rest_world doesn't use the R10 stack adjust parameter, nor does it + pick up the R3-R6 exception handling stuff. */ + +.private_extern rest_world +rest_world: + /* Pickup previous SP */ + lwz r11, 0(r1) + li r7, 0 + lwz r8, 8(r11) + li r10, 0 + b rest_world_eh_r7r8 + +.private_extern eh_rest_world_r10 +eh_rest_world_r10: + /* Pickup previous SP */ + lwz r11, 0(r1) + mr r7,r10 + lwz r8, 8(r11) + /* pickup the C++ EH data regs (R3 - R6.) */ + lwz r6,-420(r11) + lwz r5,-424(r11) + lwz r4,-428(r11) + lwz r3,-432(r11) + + b rest_world_eh_r7r8 + +/* rest_world_eh_r7r8 is jumped to -- not called! -- when we're doing + the exception-handling epilog. R7 contains the offset to add to + the SP, and R8 contains the 'real' return address. + + USES: R0 R11 R12 [R7/R8] + RETURNS: C++ EH Data registers (R3 - R6.) */ + +rest_world_eh_r7r8: + bcl 20,31,Lr7r8$pb +Lr7r8$pb: mflr r12 + lwz r11,0(r1) + /* R11 := previous SP */ + addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Lr7r8$pb) + lwz r12,lo16(L_has_vec$non_lazy_ptr-Lr7r8$pb)(r12) + lwz r0,4(r11) + /* R0 := old CR */ + lwz r12,0(r12) + /* R12 := HAS_VEC */ + mtcr r0 + cmpwi r12,0 + lmw r13,-220(r11) + beq L.rest_world_fp_eh + /* restore VRsave and V20..V31 */ + lwz r0,-224(r11) + li r12,-416 + mtspr VRsave,r0 + lvx v20,r11,r12 + li r12,-400 + lvx v21,r11,r12 + li r12,-384 + lvx v22,r11,r12 + li r12,-368 + lvx v23,r11,r12 + li r12,-352 + lvx v24,r11,r12 + li r12,-336 + lvx v25,r11,r12 + li r12,-320 + lvx v26,r11,r12 + li r12,-304 + lvx v27,r11,r12 + li r12,-288 + lvx v28,r11,r12 + li r12,-272 + lvx v29,r11,r12 + li r12,-256 + lvx v30,r11,r12 + li r12,-240 + lvx v31,r11,r12 + +L.rest_world_fp_eh: + lfd f14,-144(r11) + lfd f15,-136(r11) + lfd f16,-128(r11) + lfd f17,-120(r11) + lfd f18,-112(r11) + lfd f19,-104(r11) + lfd f20,-96(r11) + lfd f21,-88(r11) + lfd f22,-80(r11) + lfd f23,-72(r11) + lfd f24,-64(r11) + lfd f25,-56(r11) + lfd f26,-48(r11) + lfd f27,-40(r11) + lfd f28,-32(r11) + lfd f29,-24(r11) + lfd f30,-16(r11) + /* R8 is the exception-handler's address */ + mtctr r8 + lfd f31,-8(r11) + /* set SP to original value + R7 offset */ + add r1,r11,r7 + bctr diff --git a/libgcc/config/rs6000/e500crtres32gpr.S b/libgcc/config/rs6000/e500crtres32gpr.S new file mode 100644 index 0000000..6fbff82 --- /dev/null +++ b/libgcc/config/rs6000/e500crtres32gpr.S @@ -0,0 +1,73 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for restoring 32-bit integer registers, called by the compiler. */ +/* "Bare" versions that simply return to their caller. */ + +HIDDEN_FUNC(_rest32gpr_14) lwz 14,-72(11) +HIDDEN_FUNC(_rest32gpr_15) lwz 15,-68(11) +HIDDEN_FUNC(_rest32gpr_16) lwz 16,-64(11) +HIDDEN_FUNC(_rest32gpr_17) lwz 17,-60(11) +HIDDEN_FUNC(_rest32gpr_18) lwz 18,-56(11) +HIDDEN_FUNC(_rest32gpr_19) lwz 19,-52(11) +HIDDEN_FUNC(_rest32gpr_20) lwz 20,-48(11) +HIDDEN_FUNC(_rest32gpr_21) lwz 21,-44(11) +HIDDEN_FUNC(_rest32gpr_22) lwz 22,-40(11) +HIDDEN_FUNC(_rest32gpr_23) lwz 23,-36(11) +HIDDEN_FUNC(_rest32gpr_24) lwz 24,-32(11) +HIDDEN_FUNC(_rest32gpr_25) lwz 25,-28(11) +HIDDEN_FUNC(_rest32gpr_26) lwz 26,-24(11) +HIDDEN_FUNC(_rest32gpr_27) lwz 27,-20(11) +HIDDEN_FUNC(_rest32gpr_28) lwz 28,-16(11) +HIDDEN_FUNC(_rest32gpr_29) lwz 29,-12(11) +HIDDEN_FUNC(_rest32gpr_30) lwz 30,-8(11) +HIDDEN_FUNC(_rest32gpr_31) lwz 31,-4(11) + blr +FUNC_END(_rest32gpr_31) +FUNC_END(_rest32gpr_30) +FUNC_END(_rest32gpr_29) +FUNC_END(_rest32gpr_28) +FUNC_END(_rest32gpr_27) +FUNC_END(_rest32gpr_26) +FUNC_END(_rest32gpr_25) +FUNC_END(_rest32gpr_24) +FUNC_END(_rest32gpr_23) +FUNC_END(_rest32gpr_22) +FUNC_END(_rest32gpr_21) +FUNC_END(_rest32gpr_20) +FUNC_END(_rest32gpr_19) +FUNC_END(_rest32gpr_18) +FUNC_END(_rest32gpr_17) +FUNC_END(_rest32gpr_16) +FUNC_END(_rest32gpr_15) +FUNC_END(_rest32gpr_14) + +#endif diff --git a/libgcc/config/rs6000/e500crtres64gpr.S b/libgcc/config/rs6000/e500crtres64gpr.S new file mode 100644 index 0000000..5182e55 --- /dev/null +++ b/libgcc/config/rs6000/e500crtres64gpr.S @@ -0,0 +1,73 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for restoring 64-bit integer registers, called by the compiler. */ +/* "Bare" versions that return to their caller. */ + +HIDDEN_FUNC(_rest64gpr_14) evldd 14,0(11) +HIDDEN_FUNC(_rest64gpr_15) evldd 15,8(11) +HIDDEN_FUNC(_rest64gpr_16) evldd 16,16(11) +HIDDEN_FUNC(_rest64gpr_17) evldd 17,24(11) +HIDDEN_FUNC(_rest64gpr_18) evldd 18,32(11) +HIDDEN_FUNC(_rest64gpr_19) evldd 19,40(11) +HIDDEN_FUNC(_rest64gpr_20) evldd 20,48(11) +HIDDEN_FUNC(_rest64gpr_21) evldd 21,56(11) +HIDDEN_FUNC(_rest64gpr_22) evldd 22,64(11) +HIDDEN_FUNC(_rest64gpr_23) evldd 23,72(11) +HIDDEN_FUNC(_rest64gpr_24) evldd 24,80(11) +HIDDEN_FUNC(_rest64gpr_25) evldd 25,88(11) +HIDDEN_FUNC(_rest64gpr_26) evldd 26,96(11) +HIDDEN_FUNC(_rest64gpr_27) evldd 27,104(11) +HIDDEN_FUNC(_rest64gpr_28) evldd 28,112(11) +HIDDEN_FUNC(_rest64gpr_29) evldd 29,120(11) +HIDDEN_FUNC(_rest64gpr_30) evldd 30,128(11) +HIDDEN_FUNC(_rest64gpr_31) evldd 31,136(11) + blr +FUNC_END(_rest64gpr_31) +FUNC_END(_rest64gpr_30) +FUNC_END(_rest64gpr_29) +FUNC_END(_rest64gpr_28) +FUNC_END(_rest64gpr_27) +FUNC_END(_rest64gpr_26) +FUNC_END(_rest64gpr_25) +FUNC_END(_rest64gpr_24) +FUNC_END(_rest64gpr_23) +FUNC_END(_rest64gpr_22) +FUNC_END(_rest64gpr_21) +FUNC_END(_rest64gpr_20) +FUNC_END(_rest64gpr_19) +FUNC_END(_rest64gpr_18) +FUNC_END(_rest64gpr_17) +FUNC_END(_rest64gpr_16) +FUNC_END(_rest64gpr_15) +FUNC_END(_rest64gpr_14) + +#endif diff --git a/libgcc/config/rs6000/e500crtres64gprctr.S b/libgcc/config/rs6000/e500crtres64gprctr.S new file mode 100644 index 0000000..74309d6 --- /dev/null +++ b/libgcc/config/rs6000/e500crtres64gprctr.S @@ -0,0 +1,90 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for restoring 64-bit integer registers where the number of + registers to be restored is passed in CTR, called by the compiler. */ + +HIDDEN_FUNC(_rest64gpr_ctr_14) evldd 14,0(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_15) evldd 15,8(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_16) evldd 16,16(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_17) evldd 17,24(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_18) evldd 18,32(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_19) evldd 19,40(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_20) evldd 20,48(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_21) evldd 21,56(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_22) evldd 22,64(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_23) evldd 23,72(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_24) evldd 24,80(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_25) evldd 25,88(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_26) evldd 26,96(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_27) evldd 27,104(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_28) evldd 28,112(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_29) evldd 29,120(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_30) evldd 30,128(11) + bdz _rest64gpr_ctr_done +HIDDEN_FUNC(_rest64gpr_ctr_31) evldd 31,136(11) +_rest64gpr_ctr_done: blr +FUNC_END(_rest64gpr_ctr_31) +FUNC_END(_rest64gpr_ctr_30) +FUNC_END(_rest64gpr_ctr_29) +FUNC_END(_rest64gpr_ctr_28) +FUNC_END(_rest64gpr_ctr_27) +FUNC_END(_rest64gpr_ctr_26) +FUNC_END(_rest64gpr_ctr_25) +FUNC_END(_rest64gpr_ctr_24) +FUNC_END(_rest64gpr_ctr_23) +FUNC_END(_rest64gpr_ctr_22) +FUNC_END(_rest64gpr_ctr_21) +FUNC_END(_rest64gpr_ctr_20) +FUNC_END(_rest64gpr_ctr_19) +FUNC_END(_rest64gpr_ctr_18) +FUNC_END(_rest64gpr_ctr_17) +FUNC_END(_rest64gpr_ctr_16) +FUNC_END(_rest64gpr_ctr_15) +FUNC_END(_rest64gpr_ctr_14) + +#endif diff --git a/libgcc/config/rs6000/e500crtrest32gpr.S b/libgcc/config/rs6000/e500crtrest32gpr.S new file mode 100644 index 0000000..4e61010 --- /dev/null +++ b/libgcc/config/rs6000/e500crtrest32gpr.S @@ -0,0 +1,75 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for restoring 32-bit integer registers, called by the compiler. */ +/* "Tail" versions that perform a tail call. */ + +HIDDEN_FUNC(_rest32gpr_14_t) lwz 14,-72(11) +HIDDEN_FUNC(_rest32gpr_15_t) lwz 15,-68(11) +HIDDEN_FUNC(_rest32gpr_16_t) lwz 16,-64(11) +HIDDEN_FUNC(_rest32gpr_17_t) lwz 17,-60(11) +HIDDEN_FUNC(_rest32gpr_18_t) lwz 18,-56(11) +HIDDEN_FUNC(_rest32gpr_19_t) lwz 19,-52(11) +HIDDEN_FUNC(_rest32gpr_20_t) lwz 20,-48(11) +HIDDEN_FUNC(_rest32gpr_21_t) lwz 21,-44(11) +HIDDEN_FUNC(_rest32gpr_22_t) lwz 22,-40(11) +HIDDEN_FUNC(_rest32gpr_23_t) lwz 23,-36(11) +HIDDEN_FUNC(_rest32gpr_24_t) lwz 24,-32(11) +HIDDEN_FUNC(_rest32gpr_25_t) lwz 25,-28(11) +HIDDEN_FUNC(_rest32gpr_26_t) lwz 26,-24(11) +HIDDEN_FUNC(_rest32gpr_27_t) lwz 27,-20(11) +HIDDEN_FUNC(_rest32gpr_28_t) lwz 28,-16(11) +HIDDEN_FUNC(_rest32gpr_29_t) lwz 29,-12(11) +HIDDEN_FUNC(_rest32gpr_30_t) lwz 30,-8(11) +HIDDEN_FUNC(_rest32gpr_31_t) lwz 31,-4(11) + lwz 0,4(11) + mr 1,11 + blr +FUNC_END(_rest32gpr_31_t) +FUNC_END(_rest32gpr_30_t) +FUNC_END(_rest32gpr_29_t) +FUNC_END(_rest32gpr_28_t) +FUNC_END(_rest32gpr_27_t) +FUNC_END(_rest32gpr_26_t) +FUNC_END(_rest32gpr_25_t) +FUNC_END(_rest32gpr_24_t) +FUNC_END(_rest32gpr_23_t) +FUNC_END(_rest32gpr_22_t) +FUNC_END(_rest32gpr_21_t) +FUNC_END(_rest32gpr_20_t) +FUNC_END(_rest32gpr_19_t) +FUNC_END(_rest32gpr_18_t) +FUNC_END(_rest32gpr_17_t) +FUNC_END(_rest32gpr_16_t) +FUNC_END(_rest32gpr_15_t) +FUNC_END(_rest32gpr_14_t) + +#endif diff --git a/libgcc/config/rs6000/e500crtrest64gpr.S b/libgcc/config/rs6000/e500crtrest64gpr.S new file mode 100644 index 0000000..090786f --- /dev/null +++ b/libgcc/config/rs6000/e500crtrest64gpr.S @@ -0,0 +1,74 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* "Tail" versions that perform a tail call. */ + +HIDDEN_FUNC(_rest64gpr_14_t) evldd 14,0(11) +HIDDEN_FUNC(_rest64gpr_15_t) evldd 15,8(11) +HIDDEN_FUNC(_rest64gpr_16_t) evldd 16,16(11) +HIDDEN_FUNC(_rest64gpr_17_t) evldd 17,24(11) +HIDDEN_FUNC(_rest64gpr_18_t) evldd 18,32(11) +HIDDEN_FUNC(_rest64gpr_19_t) evldd 19,40(11) +HIDDEN_FUNC(_rest64gpr_20_t) evldd 20,48(11) +HIDDEN_FUNC(_rest64gpr_21_t) evldd 21,56(11) +HIDDEN_FUNC(_rest64gpr_22_t) evldd 22,64(11) +HIDDEN_FUNC(_rest64gpr_23_t) evldd 23,72(11) +HIDDEN_FUNC(_rest64gpr_24_t) evldd 24,80(11) +HIDDEN_FUNC(_rest64gpr_25_t) evldd 25,88(11) +HIDDEN_FUNC(_rest64gpr_26_t) evldd 26,96(11) +HIDDEN_FUNC(_rest64gpr_27_t) evldd 27,104(11) +HIDDEN_FUNC(_rest64gpr_28_t) evldd 28,112(11) +HIDDEN_FUNC(_rest64gpr_29_t) evldd 29,120(11) +HIDDEN_FUNC(_rest64gpr_30_t) evldd 30,128(11) +HIDDEN_FUNC(_rest64gpr_31_t) lwz 0,148(11) + evldd 31,136(11) + addi 1,11,144 + blr +FUNC_END(_rest64gpr_31_t) +FUNC_END(_rest64gpr_30_t) +FUNC_END(_rest64gpr_29_t) +FUNC_END(_rest64gpr_28_t) +FUNC_END(_rest64gpr_27_t) +FUNC_END(_rest64gpr_26_t) +FUNC_END(_rest64gpr_25_t) +FUNC_END(_rest64gpr_24_t) +FUNC_END(_rest64gpr_23_t) +FUNC_END(_rest64gpr_22_t) +FUNC_END(_rest64gpr_21_t) +FUNC_END(_rest64gpr_20_t) +FUNC_END(_rest64gpr_19_t) +FUNC_END(_rest64gpr_18_t) +FUNC_END(_rest64gpr_17_t) +FUNC_END(_rest64gpr_16_t) +FUNC_END(_rest64gpr_15_t) +FUNC_END(_rest64gpr_14_t) + +#endif diff --git a/libgcc/config/rs6000/e500crtresx32gpr.S b/libgcc/config/rs6000/e500crtresx32gpr.S new file mode 100644 index 0000000..0b35245 --- /dev/null +++ b/libgcc/config/rs6000/e500crtresx32gpr.S @@ -0,0 +1,75 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for restoring 32-bit integer registers, called by the compiler. */ +/* "Exit" versions that return to the caller's caller. */ + +HIDDEN_FUNC(_rest32gpr_14_x) lwz 14,-72(11) +HIDDEN_FUNC(_rest32gpr_15_x) lwz 15,-68(11) +HIDDEN_FUNC(_rest32gpr_16_x) lwz 16,-64(11) +HIDDEN_FUNC(_rest32gpr_17_x) lwz 17,-60(11) +HIDDEN_FUNC(_rest32gpr_18_x) lwz 18,-56(11) +HIDDEN_FUNC(_rest32gpr_19_x) lwz 19,-52(11) +HIDDEN_FUNC(_rest32gpr_20_x) lwz 20,-48(11) +HIDDEN_FUNC(_rest32gpr_21_x) lwz 21,-44(11) +HIDDEN_FUNC(_rest32gpr_22_x) lwz 22,-40(11) +HIDDEN_FUNC(_rest32gpr_23_x) lwz 23,-36(11) +HIDDEN_FUNC(_rest32gpr_24_x) lwz 24,-32(11) +HIDDEN_FUNC(_rest32gpr_25_x) lwz 25,-28(11) +HIDDEN_FUNC(_rest32gpr_26_x) lwz 26,-24(11) +HIDDEN_FUNC(_rest32gpr_27_x) lwz 27,-20(11) +HIDDEN_FUNC(_rest32gpr_28_x) lwz 28,-16(11) +HIDDEN_FUNC(_rest32gpr_29_x) lwz 29,-12(11) +HIDDEN_FUNC(_rest32gpr_30_x) lwz 30,-8(11) +HIDDEN_FUNC(_rest32gpr_31_x) lwz 0,4(11) + lwz 31,-4(11) + mr 1,11 + mtlr 0 + blr +FUNC_END(_rest32gpr_31_x) +FUNC_END(_rest32gpr_30_x) +FUNC_END(_rest32gpr_29_x) +FUNC_END(_rest32gpr_28_x) +FUNC_END(_rest32gpr_27_x) +FUNC_END(_rest32gpr_26_x) +FUNC_END(_rest32gpr_25_x) +FUNC_END(_rest32gpr_24_x) +FUNC_END(_rest32gpr_23_x) +FUNC_END(_rest32gpr_22_x) +FUNC_END(_rest32gpr_21_x) +FUNC_END(_rest32gpr_20_x) +FUNC_END(_rest32gpr_19_x) +FUNC_END(_rest32gpr_18_x) +FUNC_END(_rest32gpr_17_x) +FUNC_END(_rest32gpr_16_x) +FUNC_END(_rest32gpr_15_x) +FUNC_END(_rest32gpr_14_x) + +#endif diff --git a/libgcc/config/rs6000/e500crtresx64gpr.S b/libgcc/config/rs6000/e500crtresx64gpr.S new file mode 100644 index 0000000..ce2a6cf --- /dev/null +++ b/libgcc/config/rs6000/e500crtresx64gpr.S @@ -0,0 +1,75 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* "Exit" versions that return to their caller's caller. */ + +HIDDEN_FUNC(_rest64gpr_14_x) evldd 14,0(11) +HIDDEN_FUNC(_rest64gpr_15_x) evldd 15,8(11) +HIDDEN_FUNC(_rest64gpr_16_x) evldd 16,16(11) +HIDDEN_FUNC(_rest64gpr_17_x) evldd 17,24(11) +HIDDEN_FUNC(_rest64gpr_18_x) evldd 18,32(11) +HIDDEN_FUNC(_rest64gpr_19_x) evldd 19,40(11) +HIDDEN_FUNC(_rest64gpr_20_x) evldd 20,48(11) +HIDDEN_FUNC(_rest64gpr_21_x) evldd 21,56(11) +HIDDEN_FUNC(_rest64gpr_22_x) evldd 22,64(11) +HIDDEN_FUNC(_rest64gpr_23_x) evldd 23,72(11) +HIDDEN_FUNC(_rest64gpr_24_x) evldd 24,80(11) +HIDDEN_FUNC(_rest64gpr_25_x) evldd 25,88(11) +HIDDEN_FUNC(_rest64gpr_26_x) evldd 26,96(11) +HIDDEN_FUNC(_rest64gpr_27_x) evldd 27,104(11) +HIDDEN_FUNC(_rest64gpr_28_x) evldd 28,112(11) +HIDDEN_FUNC(_rest64gpr_29_x) evldd 29,120(11) +HIDDEN_FUNC(_rest64gpr_30_x) evldd 30,128(11) +HIDDEN_FUNC(_rest64gpr_31_x) lwz 0,148(11) + evldd 31,136(11) + addi 1,11,144 + mtlr 0 + blr +FUNC_END(_rest64gpr_31_x) +FUNC_END(_rest64gpr_30_x) +FUNC_END(_rest64gpr_29_x) +FUNC_END(_rest64gpr_28_x) +FUNC_END(_rest64gpr_27_x) +FUNC_END(_rest64gpr_26_x) +FUNC_END(_rest64gpr_25_x) +FUNC_END(_rest64gpr_24_x) +FUNC_END(_rest64gpr_23_x) +FUNC_END(_rest64gpr_22_x) +FUNC_END(_rest64gpr_21_x) +FUNC_END(_rest64gpr_20_x) +FUNC_END(_rest64gpr_19_x) +FUNC_END(_rest64gpr_18_x) +FUNC_END(_rest64gpr_17_x) +FUNC_END(_rest64gpr_16_x) +FUNC_END(_rest64gpr_15_x) +FUNC_END(_rest64gpr_14_x) + +#endif diff --git a/libgcc/config/rs6000/e500crtsav32gpr.S b/libgcc/config/rs6000/e500crtsav32gpr.S new file mode 100644 index 0000000..c891030 --- /dev/null +++ b/libgcc/config/rs6000/e500crtsav32gpr.S @@ -0,0 +1,73 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for saving 32-bit integer registers, called by the compiler. */ +/* "Bare" versions that simply return to their caller. */ + +HIDDEN_FUNC(_save32gpr_14) stw 14,-72(11) +HIDDEN_FUNC(_save32gpr_15) stw 15,-68(11) +HIDDEN_FUNC(_save32gpr_16) stw 16,-64(11) +HIDDEN_FUNC(_save32gpr_17) stw 17,-60(11) +HIDDEN_FUNC(_save32gpr_18) stw 18,-56(11) +HIDDEN_FUNC(_save32gpr_19) stw 19,-52(11) +HIDDEN_FUNC(_save32gpr_20) stw 20,-48(11) +HIDDEN_FUNC(_save32gpr_21) stw 21,-44(11) +HIDDEN_FUNC(_save32gpr_22) stw 22,-40(11) +HIDDEN_FUNC(_save32gpr_23) stw 23,-36(11) +HIDDEN_FUNC(_save32gpr_24) stw 24,-32(11) +HIDDEN_FUNC(_save32gpr_25) stw 25,-28(11) +HIDDEN_FUNC(_save32gpr_26) stw 26,-24(11) +HIDDEN_FUNC(_save32gpr_27) stw 27,-20(11) +HIDDEN_FUNC(_save32gpr_28) stw 28,-16(11) +HIDDEN_FUNC(_save32gpr_29) stw 29,-12(11) +HIDDEN_FUNC(_save32gpr_30) stw 30,-8(11) +HIDDEN_FUNC(_save32gpr_31) stw 31,-4(11) + blr +FUNC_END(_save32gpr_31) +FUNC_END(_save32gpr_30) +FUNC_END(_save32gpr_29) +FUNC_END(_save32gpr_28) +FUNC_END(_save32gpr_27) +FUNC_END(_save32gpr_26) +FUNC_END(_save32gpr_25) +FUNC_END(_save32gpr_24) +FUNC_END(_save32gpr_23) +FUNC_END(_save32gpr_22) +FUNC_END(_save32gpr_21) +FUNC_END(_save32gpr_20) +FUNC_END(_save32gpr_19) +FUNC_END(_save32gpr_18) +FUNC_END(_save32gpr_17) +FUNC_END(_save32gpr_16) +FUNC_END(_save32gpr_15) +FUNC_END(_save32gpr_14) + +#endif diff --git a/libgcc/config/rs6000/e500crtsav64gpr.S b/libgcc/config/rs6000/e500crtsav64gpr.S new file mode 100644 index 0000000..2a5d3e4 --- /dev/null +++ b/libgcc/config/rs6000/e500crtsav64gpr.S @@ -0,0 +1,72 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for saving 64-bit integer registers, called by the compiler. */ + +HIDDEN_FUNC(_save64gpr_14) evstdd 14,0(11) +HIDDEN_FUNC(_save64gpr_15) evstdd 15,8(11) +HIDDEN_FUNC(_save64gpr_16) evstdd 16,16(11) +HIDDEN_FUNC(_save64gpr_17) evstdd 17,24(11) +HIDDEN_FUNC(_save64gpr_18) evstdd 18,32(11) +HIDDEN_FUNC(_save64gpr_19) evstdd 19,40(11) +HIDDEN_FUNC(_save64gpr_20) evstdd 20,48(11) +HIDDEN_FUNC(_save64gpr_21) evstdd 21,56(11) +HIDDEN_FUNC(_save64gpr_22) evstdd 22,64(11) +HIDDEN_FUNC(_save64gpr_23) evstdd 23,72(11) +HIDDEN_FUNC(_save64gpr_24) evstdd 24,80(11) +HIDDEN_FUNC(_save64gpr_25) evstdd 25,88(11) +HIDDEN_FUNC(_save64gpr_26) evstdd 26,96(11) +HIDDEN_FUNC(_save64gpr_27) evstdd 27,104(11) +HIDDEN_FUNC(_save64gpr_28) evstdd 28,112(11) +HIDDEN_FUNC(_save64gpr_29) evstdd 29,120(11) +HIDDEN_FUNC(_save64gpr_30) evstdd 30,128(11) +HIDDEN_FUNC(_save64gpr_31) evstdd 31,136(11) + blr +FUNC_END(_save64gpr_31) +FUNC_END(_save64gpr_30) +FUNC_END(_save64gpr_29) +FUNC_END(_save64gpr_28) +FUNC_END(_save64gpr_27) +FUNC_END(_save64gpr_26) +FUNC_END(_save64gpr_25) +FUNC_END(_save64gpr_24) +FUNC_END(_save64gpr_23) +FUNC_END(_save64gpr_22) +FUNC_END(_save64gpr_21) +FUNC_END(_save64gpr_20) +FUNC_END(_save64gpr_19) +FUNC_END(_save64gpr_18) +FUNC_END(_save64gpr_17) +FUNC_END(_save64gpr_16) +FUNC_END(_save64gpr_15) +FUNC_END(_save64gpr_14) + +#endif diff --git a/libgcc/config/rs6000/e500crtsav64gprctr.S b/libgcc/config/rs6000/e500crtsav64gprctr.S new file mode 100644 index 0000000..dd0bdf3 --- /dev/null +++ b/libgcc/config/rs6000/e500crtsav64gprctr.S @@ -0,0 +1,91 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for saving 64-bit integer registers where the number of + registers to be saved is passed in CTR, called by the compiler. */ +/* "Bare" versions that return to their caller. */ + +HIDDEN_FUNC(_save64gpr_ctr_14) evstdd 14,0(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_15) evstdd 15,8(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_16) evstdd 16,16(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_17) evstdd 17,24(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_18) evstdd 18,32(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_19) evstdd 19,40(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_20) evstdd 20,48(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_21) evstdd 21,56(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_22) evstdd 22,64(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_23) evstdd 23,72(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_24) evstdd 24,80(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_25) evstdd 25,88(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_26) evstdd 26,96(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_27) evstdd 27,104(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_28) evstdd 28,112(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_29) evstdd 29,120(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_30) evstdd 30,128(11) + bdz _save64gpr_ctr_done +HIDDEN_FUNC(_save64gpr_ctr_31) evstdd 31,136(11) +_save64gpr_ctr_done: blr +FUNC_END(_save64gpr_ctr_31) +FUNC_END(_save64gpr_ctr_30) +FUNC_END(_save64gpr_ctr_29) +FUNC_END(_save64gpr_ctr_28) +FUNC_END(_save64gpr_ctr_27) +FUNC_END(_save64gpr_ctr_26) +FUNC_END(_save64gpr_ctr_25) +FUNC_END(_save64gpr_ctr_24) +FUNC_END(_save64gpr_ctr_23) +FUNC_END(_save64gpr_ctr_22) +FUNC_END(_save64gpr_ctr_21) +FUNC_END(_save64gpr_ctr_20) +FUNC_END(_save64gpr_ctr_19) +FUNC_END(_save64gpr_ctr_18) +FUNC_END(_save64gpr_ctr_17) +FUNC_END(_save64gpr_ctr_16) +FUNC_END(_save64gpr_ctr_15) +FUNC_END(_save64gpr_ctr_14) + +#endif diff --git a/libgcc/config/rs6000/e500crtsavg32gpr.S b/libgcc/config/rs6000/e500crtsavg32gpr.S new file mode 100644 index 0000000..d14088e --- /dev/null +++ b/libgcc/config/rs6000/e500crtsavg32gpr.S @@ -0,0 +1,73 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for saving 32-bit integer registers, called by the compiler. */ +/* "GOT" versions that load the address of the GOT into lr before returning. */ + +HIDDEN_FUNC(_save32gpr_14_g) stw 14,-72(11) +HIDDEN_FUNC(_save32gpr_15_g) stw 15,-68(11) +HIDDEN_FUNC(_save32gpr_16_g) stw 16,-64(11) +HIDDEN_FUNC(_save32gpr_17_g) stw 17,-60(11) +HIDDEN_FUNC(_save32gpr_18_g) stw 18,-56(11) +HIDDEN_FUNC(_save32gpr_19_g) stw 19,-52(11) +HIDDEN_FUNC(_save32gpr_20_g) stw 20,-48(11) +HIDDEN_FUNC(_save32gpr_21_g) stw 21,-44(11) +HIDDEN_FUNC(_save32gpr_22_g) stw 22,-40(11) +HIDDEN_FUNC(_save32gpr_23_g) stw 23,-36(11) +HIDDEN_FUNC(_save32gpr_24_g) stw 24,-32(11) +HIDDEN_FUNC(_save32gpr_25_g) stw 25,-28(11) +HIDDEN_FUNC(_save32gpr_26_g) stw 26,-24(11) +HIDDEN_FUNC(_save32gpr_27_g) stw 27,-20(11) +HIDDEN_FUNC(_save32gpr_28_g) stw 28,-16(11) +HIDDEN_FUNC(_save32gpr_29_g) stw 29,-12(11) +HIDDEN_FUNC(_save32gpr_30_g) stw 30,-8(11) +HIDDEN_FUNC(_save32gpr_31_g) stw 31,-4(11) + b _GLOBAL_OFFSET_TABLE_-4 +FUNC_END(_save32gpr_31_g) +FUNC_END(_save32gpr_30_g) +FUNC_END(_save32gpr_29_g) +FUNC_END(_save32gpr_28_g) +FUNC_END(_save32gpr_27_g) +FUNC_END(_save32gpr_26_g) +FUNC_END(_save32gpr_25_g) +FUNC_END(_save32gpr_24_g) +FUNC_END(_save32gpr_23_g) +FUNC_END(_save32gpr_22_g) +FUNC_END(_save32gpr_21_g) +FUNC_END(_save32gpr_20_g) +FUNC_END(_save32gpr_19_g) +FUNC_END(_save32gpr_18_g) +FUNC_END(_save32gpr_17_g) +FUNC_END(_save32gpr_16_g) +FUNC_END(_save32gpr_15_g) +FUNC_END(_save32gpr_14_g) + +#endif diff --git a/libgcc/config/rs6000/e500crtsavg64gpr.S b/libgcc/config/rs6000/e500crtsavg64gpr.S new file mode 100644 index 0000000..cbad75b --- /dev/null +++ b/libgcc/config/rs6000/e500crtsavg64gpr.S @@ -0,0 +1,73 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for saving 64-bit integer registers, called by the compiler. */ +/* "GOT" versions that load the address of the GOT into lr before returning. */ + +HIDDEN_FUNC(_save64gpr_14_g) evstdd 14,0(11) +HIDDEN_FUNC(_save64gpr_15_g) evstdd 15,8(11) +HIDDEN_FUNC(_save64gpr_16_g) evstdd 16,16(11) +HIDDEN_FUNC(_save64gpr_17_g) evstdd 17,24(11) +HIDDEN_FUNC(_save64gpr_18_g) evstdd 18,32(11) +HIDDEN_FUNC(_save64gpr_19_g) evstdd 19,40(11) +HIDDEN_FUNC(_save64gpr_20_g) evstdd 20,48(11) +HIDDEN_FUNC(_save64gpr_21_g) evstdd 21,56(11) +HIDDEN_FUNC(_save64gpr_22_g) evstdd 22,64(11) +HIDDEN_FUNC(_save64gpr_23_g) evstdd 23,72(11) +HIDDEN_FUNC(_save64gpr_24_g) evstdd 24,80(11) +HIDDEN_FUNC(_save64gpr_25_g) evstdd 25,88(11) +HIDDEN_FUNC(_save64gpr_26_g) evstdd 26,96(11) +HIDDEN_FUNC(_save64gpr_27_g) evstdd 27,104(11) +HIDDEN_FUNC(_save64gpr_28_g) evstdd 28,112(11) +HIDDEN_FUNC(_save64gpr_29_g) evstdd 29,120(11) +HIDDEN_FUNC(_save64gpr_30_g) evstdd 30,128(11) +HIDDEN_FUNC(_save64gpr_31_g) evstdd 31,136(11) + b _GLOBAL_OFFSET_TABLE_-4 +FUNC_END(_save64gpr_31_g) +FUNC_END(_save64gpr_30_g) +FUNC_END(_save64gpr_29_g) +FUNC_END(_save64gpr_28_g) +FUNC_END(_save64gpr_27_g) +FUNC_END(_save64gpr_26_g) +FUNC_END(_save64gpr_25_g) +FUNC_END(_save64gpr_24_g) +FUNC_END(_save64gpr_23_g) +FUNC_END(_save64gpr_22_g) +FUNC_END(_save64gpr_21_g) +FUNC_END(_save64gpr_20_g) +FUNC_END(_save64gpr_19_g) +FUNC_END(_save64gpr_18_g) +FUNC_END(_save64gpr_17_g) +FUNC_END(_save64gpr_16_g) +FUNC_END(_save64gpr_15_g) +FUNC_END(_save64gpr_14_g) + +#endif diff --git a/libgcc/config/rs6000/e500crtsavg64gprctr.S b/libgcc/config/rs6000/e500crtsavg64gprctr.S new file mode 100644 index 0000000..238df4e --- /dev/null +++ b/libgcc/config/rs6000/e500crtsavg64gprctr.S @@ -0,0 +1,90 @@ +/* + * Special support for e500 eabi and SVR4 + * + * Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + * Written by Nathan Froyd + * + * This file 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. + * + * This file 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/>. + */ + + .section ".text" + #include "ppc-asm.h" + +#ifdef __SPE__ + +/* Routines for saving 64-bit integer registers, called by the compiler. */ +/* "GOT" versions that load the address of the GOT into lr before returning. */ + +HIDDEN_FUNC(_save64gpr_ctr_14_g) evstdd 14,0(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_15_g) evstdd 15,8(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_16_g) evstdd 16,16(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_17_g) evstdd 17,24(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_18_g) evstdd 18,32(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_19_g) evstdd 19,40(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_20_g) evstdd 20,48(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_21_g) evstdd 21,56(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_22_g) evstdd 22,64(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_23_g) evstdd 23,72(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_24_g) evstdd 24,80(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_25_g) evstdd 25,88(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_26_g) evstdd 26,96(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_27_g) evstdd 27,104(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_28_g) evstdd 28,112(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_29_g) evstdd 29,120(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_30_g) evstdd 30,128(11) + bdz _save64gpr_ctr_g_done +HIDDEN_FUNC(_save64gpr_ctr_31_g) evstdd 31,136(11) +_save64gpr_ctr_g_done: b _GLOBAL_OFFSET_TABLE_-4 +FUNC_END(_save64gpr_ctr_31_g) +FUNC_END(_save64gpr_ctr_30_g) +FUNC_END(_save64gpr_ctr_29_g) +FUNC_END(_save64gpr_ctr_28_g) +FUNC_END(_save64gpr_ctr_27_g) +FUNC_END(_save64gpr_ctr_26_g) +FUNC_END(_save64gpr_ctr_25_g) +FUNC_END(_save64gpr_ctr_24_g) +FUNC_END(_save64gpr_ctr_23_g) +FUNC_END(_save64gpr_ctr_22_g) +FUNC_END(_save64gpr_ctr_21_g) +FUNC_END(_save64gpr_ctr_20_g) +FUNC_END(_save64gpr_ctr_19_g) +FUNC_END(_save64gpr_ctr_18_g) +FUNC_END(_save64gpr_ctr_17_g) +FUNC_END(_save64gpr_ctr_16_g) +FUNC_END(_save64gpr_ctr_15_g) +FUNC_END(_save64gpr_ctr_14_g) + +#endif diff --git a/libgcc/config/rs6000/eabi.S b/libgcc/config/rs6000/eabi.S new file mode 100644 index 0000000..292d88e --- /dev/null +++ b/libgcc/config/rs6000/eabi.S @@ -0,0 +1,289 @@ +/* + * Special support for eabi and SVR4 + * + * Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008, 2009 + * Free Software Foundation, Inc. + * Written By Michael Meissner + * + * This file 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. + * + * This file 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/>. + */ + +/* Do any initializations needed for the eabi environment */ + + .section ".text" + #include "ppc-asm.h" + +#ifndef __powerpc64__ + + .section ".got2","aw" + .align 2 +.LCTOC1 = . /* +32768 */ + +/* Table of addresses */ +.Ltable = .-.LCTOC1 + .long .LCTOC1 /* address we are really at */ + +.Lsda = .-.LCTOC1 + .long _SDA_BASE_ /* address of the first small data area */ + +.Lsdas = .-.LCTOC1 + .long __SDATA_START__ /* start of .sdata/.sbss section */ + +.Lsdae = .-.LCTOC1 + .long __SBSS_END__ /* end of .sdata/.sbss section */ + +.Lsda2 = .-.LCTOC1 + .long _SDA2_BASE_ /* address of the second small data area */ + +.Lsda2s = .-.LCTOC1 + .long __SDATA2_START__ /* start of .sdata2/.sbss2 section */ + +.Lsda2e = .-.LCTOC1 + .long __SBSS2_END__ /* end of .sdata2/.sbss2 section */ + +#ifdef _RELOCATABLE +.Lgots = .-.LCTOC1 + .long __GOT_START__ /* Global offset table start */ + +.Lgotm1 = .-.LCTOC1 + .long _GLOBAL_OFFSET_TABLE_-4 /* end of GOT ptrs before BLCL + 3 reserved words */ + +.Lgotm2 = .-.LCTOC1 + .long _GLOBAL_OFFSET_TABLE_+12 /* start of GOT ptrs after BLCL + 3 reserved words */ + +.Lgote = .-.LCTOC1 + .long __GOT_END__ /* Global offset table end */ + +.Lgot2s = .-.LCTOC1 + .long __GOT2_START__ /* -mrelocatable GOT pointers start */ + +.Lgot2e = .-.LCTOC1 + .long __GOT2_END__ /* -mrelocatable GOT pointers end */ + +.Lfixups = .-.LCTOC1 + .long __FIXUP_START__ /* start of .fixup section */ + +.Lfixupe = .-.LCTOC1 + .long __FIXUP_END__ /* end of .fixup section */ + +.Lctors = .-.LCTOC1 + .long __CTOR_LIST__ /* start of .ctor section */ + +.Lctore = .-.LCTOC1 + .long __CTOR_END__ /* end of .ctor section */ + +.Ldtors = .-.LCTOC1 + .long __DTOR_LIST__ /* start of .dtor section */ + +.Ldtore = .-.LCTOC1 + .long __DTOR_END__ /* end of .dtor section */ + +.Lexcepts = .-.LCTOC1 + .long __EXCEPT_START__ /* start of .gcc_except_table section */ + +.Lexcepte = .-.LCTOC1 + .long __EXCEPT_END__ /* end of .gcc_except_table section */ + +.Linit = .-.LCTOC1 + .long .Linit_p /* address of variable to say we've been called */ + + .text + .align 2 +.Lptr: + .long .LCTOC1-.Laddr /* PC relative pointer to .got2 */ +#endif + + .data + .align 2 +.Linit_p: + .long 0 + + .text + +FUNC_START(__eabi) + +/* Eliminate -mrelocatable code if not -mrelocatable, so that this file can + be assembled with other assemblers than GAS. */ + +#ifndef _RELOCATABLE + addis 10,0,.Linit_p@ha /* init flag */ + addis 11,0,.LCTOC1@ha /* load address of .LCTOC1 */ + lwz 9,.Linit_p@l(10) /* init flag */ + addi 11,11,.LCTOC1@l + cmplwi 2,9,0 /* init flag != 0? */ + bnelr 2 /* return now, if we've been called already */ + stw 1,.Linit_p@l(10) /* store a nonzero value in the done flag */ + +#else /* -mrelocatable */ + mflr 0 + bl .Laddr /* get current address */ +.Laddr: + mflr 12 /* real address of .Laddr */ + lwz 11,(.Lptr-.Laddr)(12) /* linker generated address of .LCTOC1 */ + add 11,11,12 /* correct to real pointer */ + lwz 12,.Ltable(11) /* get linker's idea of where .Laddr is */ + lwz 10,.Linit(11) /* address of init flag */ + subf. 12,12,11 /* calculate difference */ + lwzx 9,10,12 /* done flag */ + cmplwi 2,9,0 /* init flag != 0? */ + mtlr 0 /* restore in case branch was taken */ + bnelr 2 /* return now, if we've been called already */ + stwx 1,10,12 /* store a nonzero value in the done flag */ + beq+ 0,.Lsdata /* skip if we don't need to relocate */ + +/* We need to relocate the .got2 pointers. */ + + lwz 3,.Lgot2s(11) /* GOT2 pointers start */ + lwz 4,.Lgot2e(11) /* GOT2 pointers end */ + add 3,12,3 /* adjust pointers */ + add 4,12,4 + bl FUNC_NAME(__eabi_convert) /* convert pointers in .got2 section */ + +/* Fixup the .ctor section for static constructors */ + + lwz 3,.Lctors(11) /* constructors pointers start */ + lwz 4,.Lctore(11) /* constructors pointers end */ + bl FUNC_NAME(__eabi_convert) /* convert constructors */ + +/* Fixup the .dtor section for static destructors */ + + lwz 3,.Ldtors(11) /* destructors pointers start */ + lwz 4,.Ldtore(11) /* destructors pointers end */ + bl FUNC_NAME(__eabi_convert) /* convert destructors */ + +/* Fixup the .gcc_except_table section for G++ exceptions */ + + lwz 3,.Lexcepts(11) /* exception table pointers start */ + lwz 4,.Lexcepte(11) /* exception table pointers end */ + bl FUNC_NAME(__eabi_convert) /* convert exceptions */ + +/* Fixup the addresses in the GOT below _GLOBAL_OFFSET_TABLE_-4 */ + + lwz 3,.Lgots(11) /* GOT table pointers start */ + lwz 4,.Lgotm1(11) /* GOT table pointers below _GLOBAL_OFFSET_TABLE-4 */ + bl FUNC_NAME(__eabi_convert) /* convert lower GOT */ + +/* Fixup the addresses in the GOT above _GLOBAL_OFFSET_TABLE_+12 */ + + lwz 3,.Lgotm2(11) /* GOT table pointers above _GLOBAL_OFFSET_TABLE+12 */ + lwz 4,.Lgote(11) /* GOT table pointers end */ + bl FUNC_NAME(__eabi_convert) /* convert lower GOT */ + +/* Fixup any user initialized pointers now (the compiler drops pointers to */ +/* each of the relocs that it does in the .fixup section). */ + +.Lfix: + lwz 3,.Lfixups(11) /* fixup pointers start */ + lwz 4,.Lfixupe(11) /* fixup pointers end */ + bl FUNC_NAME(__eabi_uconvert) /* convert user initialized pointers */ + +.Lsdata: + mtlr 0 /* restore link register */ +#endif /* _RELOCATABLE */ + +/* Only load up register 13 if there is a .sdata and/or .sbss section */ + lwz 3,.Lsdas(11) /* start of .sdata/.sbss section */ + lwz 4,.Lsdae(11) /* end of .sdata/.sbss section */ + cmpw 1,3,4 /* .sdata/.sbss section non-empty? */ + beq- 1,.Lsda2l /* skip loading r13 */ + + lwz 13,.Lsda(11) /* load r13 with _SDA_BASE_ address */ + +/* Only load up register 2 if there is a .sdata2 and/or .sbss2 section */ + +.Lsda2l: + lwz 3,.Lsda2s(11) /* start of .sdata/.sbss section */ + lwz 4,.Lsda2e(11) /* end of .sdata/.sbss section */ + cmpw 1,3,4 /* .sdata/.sbss section non-empty? */ + beq+ 1,.Ldone /* skip loading r2 */ + + lwz 2,.Lsda2(11) /* load r2 with _SDA2_BASE_ address */ + +/* Done adjusting pointers, return by way of doing the C++ global constructors. */ + +.Ldone: + b FUNC_NAME(__init) /* do any C++ global constructors (which returns to caller) */ +FUNC_END(__eabi) + +/* Special subroutine to convert a bunch of pointers directly. + r0 has original link register + r3 has low pointer to convert + r4 has high pointer to convert + r5 .. r10 are scratch registers + r11 has the address of .LCTOC1 in it. + r12 has the value to add to each pointer + r13 .. r31 are unchanged */ +#ifdef _RELOCATABLE +FUNC_START(__eabi_convert) + cmplw 1,3,4 /* any pointers to convert? */ + subf 5,3,4 /* calculate number of words to convert */ + bclr 4,4 /* return if no pointers */ + + srawi 5,5,2 + addi 3,3,-4 /* start-4 for use with lwzu */ + mtctr 5 + +.Lcvt: + lwzu 6,4(3) /* pointer to convert */ + cmpwi 0,6,0 + beq- .Lcvt2 /* if pointer is null, don't convert */ + + add 6,6,12 /* convert pointer */ + stw 6,0(3) +.Lcvt2: + bdnz+ .Lcvt + blr + +FUNC_END(__eabi_convert) + +/* Special subroutine to convert the pointers the user has initialized. The + compiler has placed the address of the initialized pointer into the .fixup + section. + + r0 has original link register + r3 has low pointer to convert + r4 has high pointer to convert + r5 .. r10 are scratch registers + r11 has the address of .LCTOC1 in it. + r12 has the value to add to each pointer + r13 .. r31 are unchanged */ + +FUNC_START(__eabi_uconvert) + cmplw 1,3,4 /* any pointers to convert? */ + subf 5,3,4 /* calculate number of words to convert */ + bclr 4,4 /* return if no pointers */ + + srawi 5,5,2 + addi 3,3,-4 /* start-4 for use with lwzu */ + mtctr 5 + +.Lucvt: + lwzu 6,4(3) /* next pointer to pointer to convert */ + add 6,6,12 /* adjust pointer */ + lwz 7,0(6) /* get the pointer it points to */ + stw 6,0(3) /* store adjusted pointer */ + add 7,7,12 /* adjust */ + stw 7,0(6) + bdnz+ .Lucvt + blr + +FUNC_END(__eabi_uconvert) +#endif +#endif diff --git a/libgcc/config/rs6000/t-darwin b/libgcc/config/rs6000/t-darwin index deec5e3..abb41fc 100644 --- a/libgcc/config/rs6000/t-darwin +++ b/libgcc/config/rs6000/t-darwin @@ -3,6 +3,21 @@ DARWIN_EXTRA_CRT_BUILD_CFLAGS = -mlongcall -mmacosx-version-min=10.4 crt2.o: $(srcdir)/config/rs6000/darwin-crt2.c $(crt_compile) $(DARWIN_EXTRA_CRT_BUILD_CFLAGS) -c $< -LIB2ADD += $(srcdir)/config/rs6000/ppc64-fp.c +LIB2ADD = $(srcdir)/config/rs6000/darwin-tramp.S \ + $(srcdir)/config/darwin-64.c \ + $(srcdir)/config/rs6000/darwin-fpsave.S \ + $(srcdir)/config/rs6000/darwin-gpsave.S \ + $(srcdir)/config/rs6000/darwin-world.S \ + $(srcdir)/config/rs6000/ppc64-fp.c + +LIB2ADD_ST = \ + $(srcdir)/config/rs6000/darwin-vecsave.S + +# The .S files above are designed to run on all processors, even though +# they use AltiVec instructions. +# -Wa is used because -force_cpusubtype_ALL doesn't work with -dynamiclib. +# -mmacosx-version-min=10.4 is used to provide compatibility for code from +# earlier OSX versions. +HOST_LIBGCC2_CFLAGS += -Wa,-force_cpusubtype_ALL -mmacosx-version-min=10.4 LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c diff --git a/libgcc/config/rs6000/t-darwin64 b/libgcc/config/rs6000/t-darwin64 new file mode 100644 index 0000000..eea0671 --- /dev/null +++ b/libgcc/config/rs6000/t-darwin64 @@ -0,0 +1,6 @@ +LIB2_SIDITI_CONV_FUNCS = yes + +LIB2ADD = $(srcdir)/config/rs6000/darwin-tramp.S \ + $(srcdir)/config/darwin-64.c \ + $(srcdir)/config/rs6000/darwin-world.S + diff --git a/libgcc/config/rs6000/t-linux64 b/libgcc/config/rs6000/t-linux64 index 7b08315..2b60f1a 100644 --- a/libgcc/config/rs6000/t-linux64 +++ b/libgcc/config/rs6000/t-linux64 @@ -1,2 +1,4 @@ +HOST_LIBGCC2_CFLAGS += -mno-minimal-toc + softfp_wrap_start := '\#ifndef __powerpc64__' softfp_wrap_end := '\#endif' diff --git a/libgcc/config/rs6000/t-lynx b/libgcc/config/rs6000/t-lynx new file mode 100644 index 0000000..af7f5982 --- /dev/null +++ b/libgcc/config/rs6000/t-lynx @@ -0,0 +1 @@ +LIB2ADD = $(srcdir)/config/rs6000/tramp.S diff --git a/libgcc/config/rs6000/t-netbsd b/libgcc/config/rs6000/t-netbsd new file mode 100644 index 0000000..3b4ba32 --- /dev/null +++ b/libgcc/config/rs6000/t-netbsd @@ -0,0 +1,9 @@ +LIB2ADD = $(srcdir)/config/rs6000/tramp.S + +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 diff --git a/libgcc/config/rs6000/t-ppccomm b/libgcc/config/rs6000/t-ppccomm index 174ccde..99f3867 100644 --- a/libgcc/config/rs6000/t-ppccomm +++ b/libgcc/config/rs6000/t-ppccomm @@ -1,83 +1,33 @@ -LIB2ADD += $(srcdir)/config/rs6000/ibm-ldouble.c - -LIB2ADD_ST += crtsavfpr.S crtresfpr.S \ - crtsavgpr.S crtresgpr.S \ - crtresxfpr.S crtresxgpr.S \ - e500crtres32gpr.S \ - e500crtres64gpr.S \ - e500crtres64gprctr.S \ - e500crtrest32gpr.S \ - e500crtrest64gpr.S \ - e500crtresx32gpr.S \ - e500crtresx64gpr.S \ - e500crtsav32gpr.S \ - e500crtsav64gpr.S \ - e500crtsav64gprctr.S \ - e500crtsavg32gpr.S \ - e500crtsavg64gpr.S \ - e500crtsavg64gprctr.S +LIB2ADD += $(srcdir)/config/rs6000/ibm-ldouble.c \ + $(srcdir)/config/rs6000/tramp.S + +# 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 + $(srcdir)/config/rs6000/eabi.S # We build {e,n}crti.o and {e,n}crtn.o, which serve to add begin and # end labels to all of the special sections used when we link using gcc. # Assemble startup files. -crtsavfpr.S: $(gcc_srcdir)/config/rs6000/crtsavfpr.asm - cat $(gcc_srcdir)/config/rs6000/crtsavfpr.asm >crtsavfpr.S - -crtresfpr.S: $(gcc_srcdir)/config/rs6000/crtresfpr.asm - cat $(gcc_srcdir)/config/rs6000/crtresfpr.asm >crtresfpr.S - -crtsavgpr.S: $(gcc_srcdir)/config/rs6000/crtsavgpr.asm - cat $(gcc_srcdir)/config/rs6000/crtsavgpr.asm >crtsavgpr.S - -crtresgpr.S: $(gcc_srcdir)/config/rs6000/crtresgpr.asm - cat $(gcc_srcdir)/config/rs6000/crtresgpr.asm >crtresgpr.S - -crtresxfpr.S: $(gcc_srcdir)/config/rs6000/crtresxfpr.asm - cat $(gcc_srcdir)/config/rs6000/crtresxfpr.asm >crtresxfpr.S - -crtresxgpr.S: $(gcc_srcdir)/config/rs6000/crtresxgpr.asm - cat $(gcc_srcdir)/config/rs6000/crtresxgpr.asm >crtresxgpr.S - -e500crtres32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtres32gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtres32gpr.asm >e500crtres32gpr.S - -e500crtres64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtres64gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtres64gpr.asm >e500crtres64gpr.S - -e500crtres64gprctr.S: $(gcc_srcdir)/config/rs6000/e500crtres64gprctr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtres64gprctr.asm >e500crtres64gprctr.S - -e500crtrest32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtrest32gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtrest32gpr.asm >e500crtrest32gpr.S - -e500crtrest64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtrest64gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtrest64gpr.asm >e500crtrest64gpr.S - -e500crtresx32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtresx32gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtresx32gpr.asm >e500crtresx32gpr.S - -e500crtresx64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtresx64gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtresx64gpr.asm >e500crtresx64gpr.S - -e500crtsav32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsav32gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtsav32gpr.asm >e500crtsav32gpr.S - -e500crtsav64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsav64gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtsav64gpr.asm >e500crtsav64gpr.S - -e500crtsav64gprctr.S: $(gcc_srcdir)/config/rs6000/e500crtsav64gprctr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtsav64gprctr.asm >e500crtsav64gprctr.S - -e500crtsavg32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsavg32gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtsavg32gpr.asm >e500crtsavg32gpr.S - -e500crtsavg64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsavg64gpr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtsavg64gpr.asm >e500crtsavg64gpr.S - -e500crtsavg64gprctr.S: $(gcc_srcdir)/config/rs6000/e500crtsavg64gprctr.asm - cat $(gcc_srcdir)/config/rs6000/e500crtsavg64gprctr.asm >e500crtsavg64gprctr.S - ecrti$(objext): $(srcdir)/config/rs6000/eabi-ci.S $(crt_compile) -c ecrti.S diff --git a/libgcc/config/rs6000/tramp.S b/libgcc/config/rs6000/tramp.S new file mode 100644 index 0000000..133b988 --- /dev/null +++ b/libgcc/config/rs6000/tramp.S @@ -0,0 +1,107 @@ +/* Special support for trampolines + * + * Copyright (C) 1996, 1997, 2000, 2007, 2008, 2009 Free Software Foundation, Inc. + * Written By Michael Meissner + * + * This file 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. + * + * This file 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/>. + */ + +/* Set up trampolines. */ + + .section ".text" +#include "ppc-asm.h" +#include "config.h" + +#ifndef __powerpc64__ + .type trampoline_initial,@object + .align 2 +trampoline_initial: + mflr r0 + bcl 20,31,1f +.Lfunc = .-trampoline_initial + .long 0 /* will be replaced with function address */ +.Lchain = .-trampoline_initial + .long 0 /* will be replaced with static chain */ +1: mflr r11 + mtlr r0 + lwz r0,0(r11) /* function address */ + lwz r11,4(r11) /* static chain */ + mtctr r0 + bctr + +trampoline_size = .-trampoline_initial + .size trampoline_initial,trampoline_size + + +/* R3 = stack address to store trampoline */ +/* R4 = length of trampoline area */ +/* R5 = function address */ +/* R6 = static chain */ + +FUNC_START(__trampoline_setup) + mflr r0 /* save return address */ + bcl 20,31,.LCF0 /* load up __trampoline_initial into r7 */ +.LCF0: + mflr r11 + addi r7,r11,trampoline_initial-4-.LCF0 /* trampoline address -4 */ + + li r8,trampoline_size /* verify that the trampoline is big enough */ + cmpw cr1,r8,r4 + srwi r4,r4,2 /* # words to move */ + addi r9,r3,-4 /* adjust pointer for lwzu */ + mtctr r4 + blt cr1,.Labort + + mtlr r0 + + /* Copy the instructions to the stack */ +.Lmove: + lwzu r10,4(r7) + stwu r10,4(r9) + bdnz .Lmove + + /* Store correct function and static chain */ + stw r5,.Lfunc(r3) + stw r6,.Lchain(r3) + + /* Now flush both caches */ + mtctr r4 +.Lcache: + icbi 0,r3 + dcbf 0,r3 + addi r3,r3,4 + bdnz .Lcache + + /* Finally synchronize things & return */ + sync + isync + blr + +.Labort: +#if (defined __PIC__ || defined __pic__) && defined HAVE_AS_REL16 + bcl 20,31,1f +1: mflr r30 + addis r30,r30,_GLOBAL_OFFSET_TABLE_-1b@ha + addi r30,r30,_GLOBAL_OFFSET_TABLE_-1b@l +#endif + bl JUMP_TARGET(abort) +FUNC_END(__trampoline_setup) + +#endif diff --git a/libgcc/config/s390/t-tpf b/libgcc/config/s390/t-tpf deleted file mode 100644 index 9d416ac..0000000 --- a/libgcc/config/s390/t-tpf +++ /dev/null @@ -1,2 +0,0 @@ -# Compile libgcc2.a with pic. -HOST_LIBGCC2_CFLAGS += -fPIC diff --git a/libgcc/config/sh/linux-atomic.S b/libgcc/config/sh/linux-atomic.S new file mode 100644 index 0000000..743c61b --- /dev/null +++ b/libgcc/config/sh/linux-atomic.S @@ -0,0 +1,223 @@ +/* Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + + +!! Linux specific atomic routines for the Renesas / SuperH SH CPUs. +!! Linux kernel for SH3/4 has implemented the support for software +!! atomic sequences. + +#define FUNC(X) .type X,@function +#define HIDDEN_FUNC(X) FUNC(X); .hidden X +#define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X +#define ENDFUNC(X) ENDFUNC0(X) + +#if ! __SH5__ + +#define ATOMIC_TEST_AND_SET(N,T,EXT) \ + .global __sync_lock_test_and_set_##N; \ + HIDDEN_FUNC(__sync_lock_test_and_set_##N); \ + .align 2; \ +__sync_lock_test_and_set_##N:; \ + mova 1f, r0; \ + nop; \ + mov r15, r1; \ + mov #(0f-1f), r15; \ +0: mov.##T @r4, r2; \ + mov.##T r5, @r4; \ +1: mov r1, r15; \ + rts; \ + EXT r2, r0; \ + ENDFUNC(__sync_lock_test_and_set_##N) + +ATOMIC_TEST_AND_SET (1,b,extu.b) +ATOMIC_TEST_AND_SET (2,w,extu.w) +ATOMIC_TEST_AND_SET (4,l,mov) + +#define ATOMIC_COMPARE_AND_SWAP(N,T,EXTS,EXT) \ + .global __sync_val_compare_and_swap_##N; \ + HIDDEN_FUNC(__sync_val_compare_and_swap_##N); \ + .align 2; \ +__sync_val_compare_and_swap_##N:; \ + mova 1f, r0; \ + EXTS r5, r5; \ + mov r15, r1; \ + mov #(0f-1f), r15; \ +0: mov.##T @r4, r2; \ + cmp/eq r2, r5; \ + bf 1f; \ + mov.##T r6, @r4; \ +1: mov r1, r15; \ + rts; \ + EXT r2, r0; \ + ENDFUNC(__sync_val_compare_and_swap_##N) + +ATOMIC_COMPARE_AND_SWAP (1,b,exts.b,extu.b) +ATOMIC_COMPARE_AND_SWAP (2,w,exts.w,extu.w) +ATOMIC_COMPARE_AND_SWAP (4,l,mov,mov) + +#define ATOMIC_BOOL_COMPARE_AND_SWAP(N,T,EXTS) \ + .global __sync_bool_compare_and_swap_##N; \ + HIDDEN_FUNC(__sync_bool_compare_and_swap_##N); \ + .align 2; \ +__sync_bool_compare_and_swap_##N:; \ + mova 1f, r0; \ + EXTS r5, r5; \ + mov r15, r1; \ + mov #(0f-1f), r15; \ +0: mov.##T @r4, r2; \ + cmp/eq r2, r5; \ + bf 1f; \ + mov.##T r6, @r4; \ +1: mov r1, r15; \ + rts; \ + movt r0; \ + ENDFUNC(__sync_bool_compare_and_swap_##N) + +ATOMIC_BOOL_COMPARE_AND_SWAP (1,b,exts.b) +ATOMIC_BOOL_COMPARE_AND_SWAP (2,w,exts.w) +ATOMIC_BOOL_COMPARE_AND_SWAP (4,l,mov) + +#define ATOMIC_FETCH_AND_OP(OP,N,T,EXT) \ + .global __sync_fetch_and_##OP##_##N; \ + HIDDEN_FUNC(__sync_fetch_and_##OP##_##N); \ + .align 2; \ +__sync_fetch_and_##OP##_##N:; \ + mova 1f, r0; \ + nop; \ + mov r15, r1; \ + mov #(0f-1f), r15; \ +0: mov.##T @r4, r2; \ + mov r5, r3; \ + OP r2, r3; \ + mov.##T r3, @r4; \ +1: mov r1, r15; \ + rts; \ + EXT r2, r0; \ + ENDFUNC(__sync_fetch_and_##OP##_##N) + +ATOMIC_FETCH_AND_OP(add,1,b,extu.b) +ATOMIC_FETCH_AND_OP(add,2,w,extu.w) +ATOMIC_FETCH_AND_OP(add,4,l,mov) + +ATOMIC_FETCH_AND_OP(or,1,b,extu.b) +ATOMIC_FETCH_AND_OP(or,2,w,extu.w) +ATOMIC_FETCH_AND_OP(or,4,l,mov) + +ATOMIC_FETCH_AND_OP(and,1,b,extu.b) +ATOMIC_FETCH_AND_OP(and,2,w,extu.w) +ATOMIC_FETCH_AND_OP(and,4,l,mov) + +ATOMIC_FETCH_AND_OP(xor,1,b,extu.b) +ATOMIC_FETCH_AND_OP(xor,2,w,extu.w) +ATOMIC_FETCH_AND_OP(xor,4,l,mov) + +#define ATOMIC_FETCH_AND_COMBOP(OP,OP0,OP1,N,T,EXT) \ + .global __sync_fetch_and_##OP##_##N; \ + HIDDEN_FUNC(__sync_fetch_and_##OP##_##N); \ + .align 2; \ +__sync_fetch_and_##OP##_##N:; \ + mova 1f, r0; \ + mov r15, r1; \ + mov #(0f-1f), r15; \ +0: mov.##T @r4, r2; \ + mov r5, r3; \ + OP0 r2, r3; \ + OP1 r3, r3; \ + mov.##T r3, @r4; \ +1: mov r1, r15; \ + rts; \ + EXT r2, r0; \ + ENDFUNC(__sync_fetch_and_##OP##_##N) + +ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,1,b,extu.b) +ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,2,w,extu.w) +ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,4,l,mov) + +ATOMIC_FETCH_AND_COMBOP(nand,and,not,1,b,extu.b) +ATOMIC_FETCH_AND_COMBOP(nand,and,not,2,w,extu.w) +ATOMIC_FETCH_AND_COMBOP(nand,and,not,4,l,mov) + +#define ATOMIC_OP_AND_FETCH(OP,N,T,EXT) \ + .global __sync_##OP##_and_fetch_##N; \ + HIDDEN_FUNC(__sync_##OP##_and_fetch_##N); \ + .align 2; \ +__sync_##OP##_and_fetch_##N:; \ + mova 1f, r0; \ + nop; \ + mov r15, r1; \ + mov #(0f-1f), r15; \ +0: mov.##T @r4, r2; \ + mov r5, r3; \ + OP r2, r3; \ + mov.##T r3, @r4; \ +1: mov r1, r15; \ + rts; \ + EXT r3, r0; \ + ENDFUNC(__sync_##OP##_and_fetch_##N) + +ATOMIC_OP_AND_FETCH(add,1,b,extu.b) +ATOMIC_OP_AND_FETCH(add,2,w,extu.w) +ATOMIC_OP_AND_FETCH(add,4,l,mov) + +ATOMIC_OP_AND_FETCH(or,1,b,extu.b) +ATOMIC_OP_AND_FETCH(or,2,w,extu.w) +ATOMIC_OP_AND_FETCH(or,4,l,mov) + +ATOMIC_OP_AND_FETCH(and,1,b,extu.b) +ATOMIC_OP_AND_FETCH(and,2,w,extu.w) +ATOMIC_OP_AND_FETCH(and,4,l,mov) + +ATOMIC_OP_AND_FETCH(xor,1,b,extu.b) +ATOMIC_OP_AND_FETCH(xor,2,w,extu.w) +ATOMIC_OP_AND_FETCH(xor,4,l,mov) + +#define ATOMIC_COMBOP_AND_FETCH(OP,OP0,OP1,N,T,EXT) \ + .global __sync_##OP##_and_fetch_##N; \ + HIDDEN_FUNC(__sync_##OP##_and_fetch_##N); \ + .align 2; \ +__sync_##OP##_and_fetch_##N:; \ + mova 1f, r0; \ + mov r15, r1; \ + mov #(0f-1f), r15; \ +0: mov.##T @r4, r2; \ + mov r5, r3; \ + OP0 r2, r3; \ + OP1 r3, r3; \ + mov.##T r3, @r4; \ +1: mov r1, r15; \ + rts; \ + EXT r3, r0; \ + ENDFUNC(__sync_##OP##_and_fetch_##N) + +ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,1,b,extu.b) +ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,2,w,extu.w) +ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,4,l,mov) + +ATOMIC_COMBOP_AND_FETCH(nand,and,not,1,b,extu.b) +ATOMIC_COMBOP_AND_FETCH(nand,and,not,2,w,extu.w) +ATOMIC_COMBOP_AND_FETCH(nand,and,not,4,l,mov) + +.section .note.GNU-stack,"",%progbits +.previous + +#endif /* ! __SH5__ */ diff --git a/libgcc/config/sh/t-linux b/libgcc/config/sh/t-linux index 9b1feac..d0f9240 100644 --- a/libgcc/config/sh/t-linux +++ b/libgcc/config/sh/t-linux @@ -1,6 +1,8 @@ LIB1ASMFUNCS_CACHE = _ic_invalidate _ic_invalidate_array -HOST_LIBGCC2_CFLAGS = -fpic -mieee -DNO_FPSCR_VALUES +LIB2ADD = $(srcdir)/config/sh/linux-atomic.S + +HOST_LIBGCC2_CFLAGS += -mieee -DNO_FPSCR_VALUES # Override t-slibgcc-elf-ver to export some libgcc symbols with # the symbol versions that glibc used, and hide some lib1func diff --git a/libgcc/config/sh/t-netbsd b/libgcc/config/sh/t-netbsd index 663edbf..d4df407 100644 --- a/libgcc/config/sh/t-netbsd +++ b/libgcc/config/sh/t-netbsd @@ -1 +1,5 @@ LIB1ASMFUNCS_CACHE = _ic_invalidate + +LIB2ADD = + +HOST_LIBGCC2_CFLAGS += -mieee diff --git a/libgcc/config/sh/t-sh b/libgcc/config/sh/t-sh index 2319adb..2a7bc7d 100644 --- a/libgcc/config/sh/t-sh +++ b/libgcc/config/sh/t-sh @@ -46,7 +46,7 @@ sdivsi3_i4i-Os-4-200.o: $(srcdir)/config/sh/lib1funcs-Os-4-200.S $(compile) -c -DL_sdivsi3_i4i $< udivsi3_i4i-Os-4-200.o: $(srcdir)/config/sh/lib1funcs-Os-4-200.S $(gcc_compile) -c -DL_udivsi3_i4i $< -unwind-dw2-Os-4-200.o: $(gcc_srcdir)/unwind-dw2.c +unwind-dw2-Os-4-200.o: $(srcdir)/unwind-dw2.c $(gcc_compile) $(LIBGCC2_CFLAGS) $(vis_hide) -fexceptions -Os -c $< OBJS_Os_4_200=sdivsi3_i4i-Os-4-200.o udivsi3_i4i-Os-4-200.o unwind-dw2-Os-4-200.o @@ -58,3 +58,6 @@ div_table-4-300.o: $(srcdir)/config/sh/lib1funcs-4-300.S libgcc-4-300.a: div_table-4-300.o $(AR_CREATE_FOR_TARGET) $@ div_table-4-300.o + +HOST_LIBGCC2_CFLAGS = -mieee + diff --git a/libgcc/config/sparc/t-sol2 b/libgcc/config/sparc/t-sol2 index 372522b..ea3fa63 100644 --- a/libgcc/config/sparc/t-sol2 +++ b/libgcc/config/sparc/t-sol2 @@ -3,4 +3,4 @@ # to produce a shared library, but since we don't know ahead of time when # we will be doing that, we just always use -fPIC when compiling the # routines in crtstuff.c. -CRTSTUFF_T_CFLAGS = -fPIC +CRTSTUFF_T_CFLAGS = $(PICFLAG) diff --git a/libgcc/config/spu/divmodti4.c b/libgcc/config/spu/divmodti4.c new file mode 100644 index 0000000..c63fb6b --- /dev/null +++ b/libgcc/config/spu/divmodti4.c @@ -0,0 +1,188 @@ +/* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc. + + This file 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 of the License, or (at your option) + any later version. + + This file 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 <spu_intrinsics.h> + +typedef unsigned int UTItype __attribute__ ((mode (TI))); +typedef int TItype __attribute__ ((mode (TI))); +TItype __divti3 (TItype u, TItype v); +TItype __modti3 (TItype u, TItype v); +UTItype __udivti3 (UTItype u, UTItype v); +UTItype __umodti3 (UTItype u, UTItype v); +UTItype __udivmodti4 (UTItype u, UTItype v, UTItype *w); + +union qword_UTItype + { + qword q; + UTItype t; + }; + +inline static qword +si_from_UTItype (UTItype t) +{ + union qword_UTItype u; + u.t = t; + return u.q; +} + +inline static UTItype +si_to_UTItype (qword q) +{ + union qword_UTItype u; + u.q = q; + return u.t; +} + +inline static unsigned int +count_leading_zeros (UTItype x) +{ + qword c = si_clz (*(qword *) & x); + qword cmp0 = si_cgti (c, 31); + qword cmp1 = si_and (cmp0, si_shlqbyi (cmp0, 4)); + qword cmp2 = si_and (cmp1, si_shlqbyi (cmp0, 8)); + qword s = si_a (c, si_and (cmp0, si_shlqbyi (c, 4))); + s = si_a (s, si_and (cmp1, si_shlqbyi (c, 8))); + s = si_a (s, si_and (cmp2, si_shlqbyi (c, 12))); + return si_to_uint (s); +} + +/* Based on implementation of udivmodsi4, which is essentially + * an optimized version of libgcc/udivmodsi4.c + clz %7,%2 + clz %4,%1 + il %5,1 + fsmbi %0,0 + sf %7,%4,%7 + ori %3,%1,0 + shl %5,%5,%7 + shl %4,%2,%7 +1: or %8,%0,%5 + rotmi %5,%5,-1 + clgt %6,%4,%3 + sf %7,%4,%3 + rotmi %4,%4,-1 + selb %0,%8,%0,%6 + selb %3,%7,%3,%6 +3: brnz %5,1b + */ + +UTItype +__udivmodti4 (UTItype num, UTItype den, UTItype * rp) +{ + qword shift = + si_from_uint (count_leading_zeros (den) - count_leading_zeros (num)); + qword n0 = si_from_UTItype (num); + qword d0 = si_from_UTItype (den); + qword bit = si_andi (si_fsmbi (1), 1); + qword r0 = si_il (0); + qword m1 = si_fsmbi (0x000f); + qword mask, r1, n1; + + d0 = si_shlqbybi (si_shlqbi (d0, shift), shift); + bit = si_shlqbybi (si_shlqbi (bit, shift), shift); + + do + { + r1 = si_or (r0, bit); + + // n1 = n0 - d0 in TImode + n1 = si_bg (d0, n0); + n1 = si_shlqbyi (n1, 4); + n1 = si_sf (m1, n1); + n1 = si_bgx (d0, n0, n1); + n1 = si_shlqbyi (n1, 4); + n1 = si_sf (m1, n1); + n1 = si_bgx (d0, n0, n1); + n1 = si_shlqbyi (n1, 4); + n1 = si_sf (m1, n1); + n1 = si_sfx (d0, n0, n1); + + mask = si_fsm (si_cgti (n1, -1)); + r0 = si_selb (r0, r1, mask); + n0 = si_selb (n0, n1, mask); + bit = si_rotqmbii (bit, -1); + d0 = si_rotqmbii (d0, -1); + } + while (si_to_uint (si_orx (bit))); + if (rp) + *rp = si_to_UTItype (n0); + return si_to_UTItype (r0); +} + +UTItype +__udivti3 (UTItype n, UTItype d) +{ + return __udivmodti4 (n, d, (UTItype *)0); +} + +UTItype +__umodti3 (UTItype n, UTItype d) +{ + UTItype w; + __udivmodti4 (n, d, &w); + return w; +} + +TItype +__divti3 (TItype n, TItype d) +{ + int c = 0; + TItype w; + + if (n < 0) + { + c = ~c; + n = -n; + } + if (d < 0) + { + c = ~c; + d = -d; + } + + w = __udivmodti4 (n, d, (UTItype *)0); + if (c) + w = -w; + return w; +} + +TItype +__modti3 (TItype n, TItype d) +{ + int c = 0; + TItype w; + + if (n < 0) + { + c = ~c; + n = -n; + } + if (d < 0) + { + c = ~c; + d = -d; + } + + __udivmodti4 (n, d, (UTItype *) &w); + if (c) + w = -w; + return w; +} diff --git a/libgcc/config/spu/divv2df3.c b/libgcc/config/spu/divv2df3.c new file mode 100644 index 0000000..9d5e1a5 --- /dev/null +++ b/libgcc/config/spu/divv2df3.c @@ -0,0 +1,195 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + + This file 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 of the License, or (at your option) + any later version. + + This file 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 <spu_intrinsics.h> + +vector double __divv2df3 (vector double a_in, vector double b_in); + +/* __divv2df3 divides the vector dividend a by the vector divisor b and + returns the resulting vector quotient. Maximum error about 0.5 ulp + over entire double range including denorms, compared to true result + in round-to-nearest rounding mode. Handles Inf or NaN operands and + results correctly. */ + +vector double +__divv2df3 (vector double a_in, vector double b_in) +{ + /* Variables */ + vec_int4 exp, exp_bias; + vec_uint4 no_underflow, overflow; + vec_float4 mant_bf, inv_bf; + vec_ullong2 exp_a, exp_b; + vec_ullong2 a_nan, a_zero, a_inf, a_denorm, a_denorm0; + vec_ullong2 b_nan, b_zero, b_inf, b_denorm, b_denorm0; + vec_ullong2 nan; + vec_uint4 a_exp, b_exp; + vec_ullong2 a_mant_0, b_mant_0; + vec_ullong2 a_exp_1s, b_exp_1s; + vec_ullong2 sign_exp_mask; + + vec_double2 a, b; + vec_double2 mant_a, mant_b, inv_b, q0, q1, q2, mult; + + /* Constants */ + vec_uint4 exp_mask_u32 = spu_splats((unsigned int)0x7FF00000); + vec_uchar16 splat_hi = (vec_uchar16){0,1,2,3, 0,1,2,3, 8, 9,10,11, 8,9,10,11}; + vec_uchar16 swap_32 = (vec_uchar16){4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + vec_ullong2 exp_mask = spu_splats(0x7FF0000000000000ULL); + vec_ullong2 sign_mask = spu_splats(0x8000000000000000ULL); + vec_float4 onef = spu_splats(1.0f); + vec_double2 one = spu_splats(1.0); + vec_double2 exp_53 = (vec_double2)spu_splats(0x0350000000000000ULL); + + sign_exp_mask = spu_or(sign_mask, exp_mask); + + /* Extract the floating point components from each of the operands including + * exponent and mantissa. + */ + a_exp = (vec_uint4)spu_and((vec_uint4)a_in, exp_mask_u32); + a_exp = spu_shuffle(a_exp, a_exp, splat_hi); + b_exp = (vec_uint4)spu_and((vec_uint4)b_in, exp_mask_u32); + b_exp = spu_shuffle(b_exp, b_exp, splat_hi); + + a_mant_0 = (vec_ullong2)spu_cmpeq((vec_uint4)spu_andc((vec_ullong2)a_in, sign_exp_mask), 0); + a_mant_0 = spu_and(a_mant_0, spu_shuffle(a_mant_0, a_mant_0, swap_32)); + + b_mant_0 = (vec_ullong2)spu_cmpeq((vec_uint4)spu_andc((vec_ullong2)b_in, sign_exp_mask), 0); + b_mant_0 = spu_and(b_mant_0, spu_shuffle(b_mant_0, b_mant_0, swap_32)); + + a_exp_1s = (vec_ullong2)spu_cmpeq(a_exp, exp_mask_u32); + b_exp_1s = (vec_ullong2)spu_cmpeq(b_exp, exp_mask_u32); + + /* Identify all possible special values that must be accomodated including: + * +-denorm, +-0, +-infinity, and NaNs. + */ + a_denorm0= (vec_ullong2)spu_cmpeq(a_exp, 0); + a_nan = spu_andc(a_exp_1s, a_mant_0); + a_zero = spu_and (a_denorm0, a_mant_0); + a_inf = spu_and (a_exp_1s, a_mant_0); + a_denorm = spu_andc(a_denorm0, a_zero); + + b_denorm0= (vec_ullong2)spu_cmpeq(b_exp, 0); + b_nan = spu_andc(b_exp_1s, b_mant_0); + b_zero = spu_and (b_denorm0, b_mant_0); + b_inf = spu_and (b_exp_1s, b_mant_0); + b_denorm = spu_andc(b_denorm0, b_zero); + + /* Scale denorm inputs to into normalized numbers by conditionally scaling the + * input parameters. + */ + a = spu_sub(spu_or(a_in, exp_53), spu_sel(exp_53, a_in, sign_mask)); + a = spu_sel(a_in, a, a_denorm); + + b = spu_sub(spu_or(b_in, exp_53), spu_sel(exp_53, b_in, sign_mask)); + b = spu_sel(b_in, b, b_denorm); + + /* Extract the divisor and dividend exponent and force parameters into the signed + * range [1.0,2.0) or [-1.0,2.0). + */ + exp_a = spu_and((vec_ullong2)a, exp_mask); + exp_b = spu_and((vec_ullong2)b, exp_mask); + + mant_a = spu_sel(a, one, (vec_ullong2)exp_mask); + mant_b = spu_sel(b, one, (vec_ullong2)exp_mask); + + /* Approximate the single reciprocal of b by using + * the single precision reciprocal estimate followed by one + * single precision iteration of Newton-Raphson. + */ + mant_bf = spu_roundtf(mant_b); + inv_bf = spu_re(mant_bf); + inv_bf = spu_madd(spu_nmsub(mant_bf, inv_bf, onef), inv_bf, inv_bf); + + /* Perform 2 more Newton-Raphson iterations in double precision. The + * result (q1) is in the range (0.5, 2.0). + */ + inv_b = spu_extend(inv_bf); + inv_b = spu_madd(spu_nmsub(mant_b, inv_b, one), inv_b, inv_b); + q0 = spu_mul(mant_a, inv_b); + q1 = spu_madd(spu_nmsub(mant_b, q0, mant_a), inv_b, q0); + + /* Determine the exponent correction factor that must be applied + * to q1 by taking into account the exponent of the normalized inputs + * and the scale factors that were applied to normalize them. + */ + exp = spu_rlmaska(spu_sub((vec_int4)exp_a, (vec_int4)exp_b), -20); + exp = spu_add(exp, (vec_int4)spu_add(spu_and((vec_int4)a_denorm, -0x34), spu_and((vec_int4)b_denorm, 0x34))); + + /* Bias the quotient exponent depending on the sign of the exponent correction + * factor so that a single multiplier will ensure the entire double precision + * domain (including denorms) can be achieved. + * + * exp bias q1 adjust exp + * ===== ======== ========== + * positive 2^+65 -65 + * negative 2^-64 +64 + */ + exp_bias = spu_xor(spu_rlmaska(exp, -31), 64); + exp = spu_sub(exp, exp_bias); + + q1 = spu_sel(q1, (vec_double2)spu_add((vec_int4)q1, spu_sl(exp_bias, 20)), exp_mask); + + /* Compute a multiplier (mult) to applied to the quotient (q1) to produce the + * expected result. On overflow, clamp the multiplier to the maximum non-infinite + * number in case the rounding mode is not round-to-nearest. + */ + exp = spu_add(exp, 0x3FF); + no_underflow = spu_cmpgt(exp, 0); + overflow = spu_cmpgt(exp, 0x7FE); + exp = spu_and(spu_sl(exp, 20), (vec_int4)no_underflow); + exp = spu_and(exp, (vec_int4)exp_mask); + + mult = spu_sel((vec_double2)exp, (vec_double2)(spu_add((vec_uint4)exp_mask, -1)), (vec_ullong2)overflow); + + /* Handle special value conditions. These include: + * + * 1) IF either operand is a NaN OR both operands are 0 or INFINITY THEN a NaN + * results. + * 2) ELSE IF the dividend is an INFINITY OR the divisor is 0 THEN a INFINITY results. + * 3) ELSE IF the dividend is 0 OR the divisor is INFINITY THEN a 0 results. + */ + mult = spu_andc(mult, (vec_double2)spu_or(a_zero, b_inf)); + mult = spu_sel(mult, (vec_double2)exp_mask, spu_or(a_inf, b_zero)); + + nan = spu_or(a_nan, b_nan); + nan = spu_or(nan, spu_and(a_zero, b_zero)); + nan = spu_or(nan, spu_and(a_inf, b_inf)); + + mult = spu_or(mult, (vec_double2)nan); + + /* Scale the final quotient */ + + q2 = spu_mul(q1, mult); + + return (q2); +} + + +/* We use the same function for vector and scalar division. Provide the + scalar entry point as an alias. */ +double __divdf3 (double a, double b) + __attribute__ ((__alias__ ("__divv2df3"))); + +/* Some toolchain builds used the __fast_divdf3 name for this helper function. + Provide this as another alternate entry point for compatibility. */ +double __fast_divdf3 (double a, double b) + __attribute__ ((__alias__ ("__divv2df3"))); + diff --git a/libgcc/config/spu/float_disf.c b/libgcc/config/spu/float_disf.c new file mode 100644 index 0000000..0f4fe3d --- /dev/null +++ b/libgcc/config/spu/float_disf.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2008, 2009 Free Software Foundation, Inc. + + This file 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 of the License, or (at your option) + any later version. + + This file 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/>. */ + +/* Prototype. */ +float __floatdisf (long long x); + +float __floatdisf (long long x) +{ + /* The SPU back-end now generates inline code for this conversion. + This file is solely used to provide the __floatdisf functions + for objects generated with prior versions of GCC. */ + return x; +} diff --git a/libgcc/config/spu/float_unsdidf.c b/libgcc/config/spu/float_unsdidf.c new file mode 100644 index 0000000..4fdf0b8 --- /dev/null +++ b/libgcc/config/spu/float_unsdidf.c @@ -0,0 +1,54 @@ +/* Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc. + + This file 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 of the License, or (at your option) + any later version. + + This file 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 <spu_intrinsics.h> +const unsigned char __didf_scale[16] __attribute__ ((__aligned__ (16))) = { + 0x00, 0x00, 0x04, 0x3e, + 0x00, 0x00, 0x04, 0x1e, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; +const unsigned char __didf_pat[16] __attribute__ ((__aligned__ (16))) = { + 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x80, 0x80, + 0x06, 0x07, 0x14, 0x15, + 0x16, 0x17, 0x80, 0x80 +}; + +/* double __float_unsdidf (unsigned long long int) + Construct two exact doubles representing the high and low parts (in + parallel), then add them. */ +qword __float_unsdidf (qword DI); +qword +__float_unsdidf (qword DI) +{ + qword t0, t1, t2, t3, t4, t5, t6, t7, t8; + t0 = si_clz (DI); + t1 = si_shl (DI, t0); + t2 = si_ceqi (t0, 32); + t3 = si_sf (t0, *(const qword *) __didf_scale); + t4 = si_a (t1, t1); + t5 = si_andc (t3, t2); + t6 = si_shufb (t5, t4, *(const qword *) __didf_pat); + t7 = si_shlqbii (t6, 4); + t8 = si_shlqbyi (t7, 8); + return si_dfa (t7, t8); +} diff --git a/libgcc/config/spu/float_unsdisf.c b/libgcc/config/spu/float_unsdisf.c new file mode 100644 index 0000000..7af120e --- /dev/null +++ b/libgcc/config/spu/float_unsdisf.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2008, 2009 Free Software Foundation, Inc. + + This file 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 of the License, or (at your option) + any later version. + + This file 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/>. */ + +/* Prototype. */ +float __floatundisf (unsigned long long x); + +float __floatundisf (unsigned long long x) +{ + /* The SPU back-end now generates inline code for this conversion. + This file is solely used to provide the __floatundisf function + for objects generated with prior versions of GCC. */ + return x; +} diff --git a/libgcc/config/spu/float_unssidf.c b/libgcc/config/spu/float_unssidf.c new file mode 100644 index 0000000..b255f81 --- /dev/null +++ b/libgcc/config/spu/float_unssidf.c @@ -0,0 +1,45 @@ +/* Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc. + + This file 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 of the License, or (at your option) + any later version. + + This file 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 <spu_intrinsics.h> +const unsigned char __sidf_pat[16] __attribute__ ((__aligned__ (16))) = { + 0x02, 0x03, 0x10, 0x11, + 0x12, 0x13, 0x80, 0x80, + 0x06, 0x07, 0x14, 0x15, + 0x16, 0x17, 0x80, 0x80 +}; + +/* double __float_unssidf (unsigned int SI) */ +qword __float_unssidf (qword SI); +qword +__float_unssidf (qword SI) +{ + qword t0, t1, t2, t3, t4, t5, t6, t7; + t0 = si_clz (SI); + t1 = si_il (1054); + t2 = si_shl (SI, t0); + t3 = si_ceqi (t0, 32); + t4 = si_sf (t0, t1); + t5 = si_a (t2, t2); + t6 = si_andc (t4, t3); + t7 = si_shufb (t6, t5, *(const qword *) __sidf_pat); + return si_shlqbii (t7, 4); +} diff --git a/libgcc/config/spu/mfc_multi_tag_release.c b/libgcc/config/spu/mfc_multi_tag_release.c new file mode 100644 index 0000000..62eb2be --- /dev/null +++ b/libgcc/config/spu/mfc_multi_tag_release.c @@ -0,0 +1,72 @@ +/* Copyright (C) 2007, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <spu_mfcio.h> +extern vector unsigned int __mfc_tag_table; + +/* Release a sequential group of tags from exclusive use. The sequential + group of tags is the range starting from <first_tag> through + <first_tag>+<number_of_tags>-1. Upon sucessful release, MFC_DMA_TAG_VALID + is returned and the tags become available for future reservation. + + If the specified tags were not previously reserved, no action is + taken and MFC_DMA_TAG_INVALID is returned. */ + +unsigned int +__mfc_multi_tag_release (unsigned int first_tag, unsigned int number_of_tags) +{ + vector unsigned int table_copy, tmp, tmp1; + vector unsigned int one = (vector unsigned int) + { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + vector unsigned int is_invalid; + unsigned int last_tag; + vector unsigned int has_been_reserved; + + last_tag = first_tag + number_of_tags; + + table_copy = spu_sl (one, number_of_tags); + table_copy = spu_rl (table_copy, -last_tag); + table_copy = spu_xor (table_copy, -1); + + /* Make sure the tags are in range and valid. */ + tmp = spu_cmpgt (spu_promote(last_tag, 0), 32); + tmp1 = spu_cmpgt (spu_promote(number_of_tags, 0), 32); + is_invalid = spu_cmpgt (spu_promote(first_tag, 0), 31); + + /* All bits are set to 1 if invalid, 0 if valid. */ + is_invalid = spu_or (tmp, is_invalid); + is_invalid = spu_or (tmp1, is_invalid); + + /* check whether these tags have been reserved */ + tmp = spu_rlmask (one, (int)-number_of_tags); + tmp1 = spu_sl (__mfc_tag_table, first_tag); + has_been_reserved = spu_cmpgt(tmp1, tmp); + + is_invalid = spu_or (has_been_reserved, is_invalid); + + table_copy = spu_sel (__mfc_tag_table, table_copy, table_copy); + __mfc_tag_table = spu_sel (table_copy, __mfc_tag_table, is_invalid); + + return spu_extract (is_invalid, 0); +} + diff --git a/libgcc/config/spu/mfc_multi_tag_reserve.c b/libgcc/config/spu/mfc_multi_tag_reserve.c new file mode 100644 index 0000000..06d7025 --- /dev/null +++ b/libgcc/config/spu/mfc_multi_tag_reserve.c @@ -0,0 +1,84 @@ +/* Copyright (C) 2007, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <spu_mfcio.h> +extern vector unsigned int __mfc_tag_table; + +/* Reserve a sequential group of tags for exclusive use. The number of + tags to be reserved is specified by the <number_of_tags> parameter. + This routine returns the first tag ID for a sequential list of + available tags and marks them as reserved. The reserved group + of tags is in the range starting from the returned tag through + the returned tag + <number_of_tags>-1. + + If the number of tags requested exceeds the number of available + sequential tags, then MFC_DMA_TAG_INVALID is returned indicating + that the request could not be serviced. */ + +unsigned int +__mfc_multi_tag_reserve (unsigned int number_of_tags) +{ + vector unsigned int table_copy; + vector unsigned int one = (vector unsigned int) + { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + vector unsigned int count_busy, is_valid; + vector unsigned int count_total; + vector unsigned int count_avail = (vector unsigned int) { 0, 0, 0, 0 }; + vector unsigned int index = (vector unsigned int) { 0, 0, 0, 0 }; + + table_copy = __mfc_tag_table; + + + /* count_busy: number of consecutive busy tags + count_avail: number of consecutive free tags + table_copy: temporary copy of the tag table + count_total: sum of count_busy and count_avail + index: index of the current working tag */ + do + { + table_copy = spu_sl (table_copy, count_avail); + + count_busy = spu_cntlz (table_copy); + table_copy = spu_sl (table_copy, count_busy); + count_avail = spu_cntlz (spu_xor(table_copy, -1)); + count_total = spu_add (count_busy, count_avail); + index = spu_add (index, count_total); + } + while (spu_extract (count_avail, 0) < number_of_tags + && spu_extract (table_copy, 0) != 0); + + index = spu_sub (index, count_avail); + + /* is_valid is set to 0xFFFFFFFF if table_copy == 0, 0 otherwise. */ + is_valid = spu_cmpeq (table_copy, 0); + index = spu_sel (index, is_valid, is_valid); + + /* Now I need to actually mark the tags as used. */ + table_copy = spu_sl (one, number_of_tags); + table_copy = spu_rl (table_copy, -number_of_tags - spu_extract (index, 0)); + table_copy = spu_sel (table_copy, __mfc_tag_table, table_copy); + __mfc_tag_table = spu_sel (table_copy, __mfc_tag_table, is_valid); + + return spu_extract (index, 0); +} + diff --git a/libgcc/config/spu/mfc_tag_release.c b/libgcc/config/spu/mfc_tag_release.c new file mode 100644 index 0000000..d59c571 --- /dev/null +++ b/libgcc/config/spu/mfc_tag_release.c @@ -0,0 +1,59 @@ +/* Copyright (C) 2007, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <spu_mfcio.h> +extern vector unsigned int __mfc_tag_table; + +/* Release the specified DMA tag from exclusive use. Once released, the + tag is available for future reservation. Upon sucessful release, + MFC_DMA_TAG_VALID is returned. If the specified tag is not in the + range 0 to 31, or had not been reserved, no action is taken and + MFC_DMA_TAG_INVALID is returned. */ + +unsigned int +__mfc_tag_release (unsigned int tag) +{ + vector unsigned int is_invalid; + vector unsigned int mask = (vector unsigned int) + { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; + vector signed int zero = (vector signed int) { 0, 0, 0, 0 }; + + vector signed int has_been_reserved; + + /* Check if the tag is out of range. */ + is_invalid = spu_cmpgt (spu_promote (tag, 0), 31); + + /* Check whether the tag has been reserved, set to all 1 if has not + been reserved, 0 otherwise. */ + has_been_reserved = (vector signed int) spu_rl (__mfc_tag_table, tag); + has_been_reserved = (vector signed int) spu_cmpgt (zero, has_been_reserved); + + /* Set invalid. */ + is_invalid = spu_or ((vector unsigned int) has_been_reserved, is_invalid); + + mask = spu_rlmask (mask, (int)(-tag)); + __mfc_tag_table = spu_or (__mfc_tag_table, mask); + + return spu_extract(is_invalid, 0); +} + diff --git a/libgcc/config/spu/mfc_tag_reserve.c b/libgcc/config/spu/mfc_tag_reserve.c new file mode 100644 index 0000000..23b4817 --- /dev/null +++ b/libgcc/config/spu/mfc_tag_reserve.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2007, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <spu_mfcio.h> +extern vector unsigned int __mfc_tag_table; + +/* Reserves a DMA tag for exclusive use. This routine returns an available + tag id in the range 0 to 31 and marks the tag as reserved. If no tags + are available, MFC_DMA_TAG_INVALID is returned indicating that all tags + are already reserved. */ + +unsigned int +__mfc_tag_reserve (void) +{ + vector unsigned int mask = (vector unsigned int) + { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; + vector unsigned int count_zeros, is_valid; + vector signed int count_neg; + + count_zeros = spu_cntlz (__mfc_tag_table); + count_neg = spu_sub (0, (vector signed int) count_zeros); + + mask = spu_rlmask (mask, (vector signed int) count_neg); + __mfc_tag_table = spu_andc (__mfc_tag_table, mask); + + is_valid = spu_cmpeq (count_zeros, 32); + count_zeros = spu_sel (count_zeros, is_valid, is_valid); + + return spu_extract (count_zeros, 0); +} + diff --git a/libgcc/config/spu/mfc_tag_table.c b/libgcc/config/spu/mfc_tag_table.c new file mode 100644 index 0000000..bd08c58 --- /dev/null +++ b/libgcc/config/spu/mfc_tag_table.c @@ -0,0 +1,39 @@ +/* Copyright (C) 2007, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +/* The free tag table used by the MFC tag manager, with tag0 + reserved for the overlay manager. */ +__vector unsigned int +__mfc_tag_table = (__vector unsigned int) { 0x7FFFFFFF, -1, -1, -1 }; + +/* Arrange to release tag0 if overlays are not present. */ +static void __mfc_tag_init (void) __attribute__ ((constructor)); + +static void +__mfc_tag_init (void) +{ + extern void _ovly_table __attribute__ ((weak)); + + if (&_ovly_table == 0) + __mfc_tag_table = (__vector unsigned int) { -1, -1, -1, -1 }; +} diff --git a/libgcc/config/spu/multi3.c b/libgcc/config/spu/multi3.c new file mode 100644 index 0000000..b8b0e90 --- /dev/null +++ b/libgcc/config/spu/multi3.c @@ -0,0 +1,119 @@ +/* Copyright (C) 2008, 2009 Free Software Foundation, Inc. + + This file 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 of the License, or (at your option) + any later version. + + This file 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 <spu_intrinsics.h> + +typedef int TItype __attribute__ ((mode (TI))); + +union qword_TItype + { + qword q; + TItype t; + }; + +inline static qword +si_from_TItype (TItype t) +{ + union qword_TItype u; + u.t = t; + return u.q; +} + +inline static TItype +si_to_TItype (qword q) +{ + union qword_TItype u; + u.q = q; + return u.t; +} + +/* A straight forward vectorization and unrolling of + * short l[8], r[8]; + * TItype total = 0; + * for (i = 0; i < 8; i++) + * for (j = 0; j < 8; j++) + * total += (TItype)((l[7-i] * r[7-j]) << (16 * (i + j))); + */ +TItype +__multi3 (TItype l, TItype r) +{ + qword u = si_from_TItype (l); + qword v = si_from_TItype (r); + qword splat0 = si_shufb (v, v, si_ilh (0x0001)); + qword splat1 = si_shufb (v, v, si_ilh (0x0203)); + qword splat2 = si_shufb (v, v, si_ilh (0x0405)); + qword splat3 = si_shufb (v, v, si_ilh (0x0607)); + qword splat4 = si_shufb (v, v, si_ilh (0x0809)); + qword splat5 = si_shufb (v, v, si_ilh (0x0a0b)); + qword splat6 = si_shufb (v, v, si_ilh (0x0c0d)); + qword splat7 = si_shufb (v, v, si_ilh (0x0e0f)); + + qword part0l = si_shlqbyi (si_mpyu (u, splat0), 14); + qword part1h = si_shlqbyi (si_mpyhhu (u, splat1), 14); + qword part1l = si_shlqbyi (si_mpyu (u, splat1), 12); + qword part2h = si_shlqbyi (si_mpyhhu (u, splat2), 12); + qword part2l = si_shlqbyi (si_mpyu (u, splat2), 10); + qword part3h = si_shlqbyi (si_mpyhhu (u, splat3), 10); + qword part3l = si_shlqbyi (si_mpyu (u, splat3), 8); + qword part4h = si_shlqbyi (si_mpyhhu (u, splat4), 8); + qword part4l = si_shlqbyi (si_mpyu (u, splat4), 6); + qword part5h = si_shlqbyi (si_mpyhhu (u, splat5), 6); + qword part5l = si_shlqbyi (si_mpyu (u, splat5), 4); + qword part6h = si_shlqbyi (si_mpyhhu (u, splat6), 4); + qword part6l = si_shlqbyi (si_mpyu (u, splat6), 2); + qword part7h = si_shlqbyi (si_mpyhhu (u, splat7), 2); + qword part7l = si_mpyu (u, splat7); + + qword carry, total0, total1, total2, total3, total4; + qword total5, total6, total7, total8, total9, total10; + qword total; + + total0 = si_a (si_a (si_a (part0l, part1h), si_a (part1l, part2h)), part7l); + total1 = si_a (part2l, part3h); + total2 = si_a (part3l, part4h); + total3 = si_a (part4l, part5h); + total4 = si_a (part5l, part6h); + total5 = si_a (part6l, part7h); + total6 = si_a (total0, total1); + total7 = si_a (total2, total3); + total8 = si_a (total4, total5); + total9 = si_a (total6, total7); + total10 = si_a (total8, total9); + + carry = si_cg (part2l, part3h); + carry = si_a (carry, si_cg (part3l, part4h)); + carry = si_a (carry, si_cg (part4l, part5h)); + carry = si_a (carry, si_cg (part5l, part6h)); + carry = si_a (carry, si_cg (part6l, part7h)); + carry = si_a (carry, si_cg (total0, total1)); + carry = si_a (carry, si_cg (total2, total3)); + carry = si_a (carry, si_cg (total4, total5)); + carry = si_a (carry, si_cg (total6, total7)); + carry = si_a (carry, si_cg (total8, total9)); + carry = si_shlqbyi (carry, 4); + + total = si_cg (total10, carry); + total = si_shlqbyi (total, 4); + total = si_cgx (total10, carry, total); + total = si_shlqbyi (total, 4); + total = si_addx (total10, carry, total); + return si_to_TItype (total); +} diff --git a/libgcc/config/spu/t-elf b/libgcc/config/spu/t-elf index 130d561..83616c1 100644 --- a/libgcc/config/spu/t-elf +++ b/libgcc/config/spu/t-elf @@ -2,6 +2,30 @@ # FIXME: This is the default. CRTSTUFF_T_CFLAGS = +# We exclude those because the libgcc2.c default versions do not support +# the SPU single-precision format (round towards zero). We provide our +# own versions below and/or via direct expansion. +LIB2ADD = _floatdisf _floatundisf _floattisf _floatunstisf + +LIB2ADD_ST = $(srcdir)/config/spu/float_unssidf.c \ + $(srcdir)/config/spu/float_unsdidf.c \ + $(srcdir)/config/spu/float_unsdisf.c \ + $(srcdir)/config/spu/float_disf.c \ + $(srcdir)/config/spu/mfc_tag_table.c \ + $(srcdir)/config/spu/mfc_tag_reserve.c \ + $(srcdir)/config/spu/mfc_tag_release.c \ + $(srcdir)/config/spu/mfc_multi_tag_reserve.c \ + $(srcdir)/config/spu/mfc_multi_tag_release.c \ + $(srcdir)/config/spu/multi3.c \ + $(srcdir)/config/spu/divmodti4.c \ + $(srcdir)/config/spu/divv2df3.c + +# Build TImode conversion routines to support Fortran 128-bit +# integer data types. +LIB2_SIDITI_CONV_FUNCS = yes + +HOST_LIBGCC2_CFLAGS += -mwarn-reloc -D__IN_LIBGCC2 + # Neither gcc or newlib seem to have a standard way to generate multiple # crt*.o files. So we don't use the standard crt0.o name anymore. diff --git a/libgcc/config/stormy16/ashlsi3.c b/libgcc/config/stormy16/ashlsi3.c new file mode 100644 index 0000000..0ef42ad --- /dev/null +++ b/libgcc/config/stormy16/ashlsi3.c @@ -0,0 +1,2 @@ +#define XSTORMY16_ASHLSI3 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/ashrsi3.c b/libgcc/config/stormy16/ashrsi3.c new file mode 100644 index 0000000..67bcbbb --- /dev/null +++ b/libgcc/config/stormy16/ashrsi3.c @@ -0,0 +1,2 @@ +#define XSTORMY16_ASHRSI3 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/clzhi2.c b/libgcc/config/stormy16/clzhi2.c new file mode 100644 index 0000000..350ef41 --- /dev/null +++ b/libgcc/config/stormy16/clzhi2.c @@ -0,0 +1,2 @@ +#define XSTORMY16_CLZHI2 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/cmpsi2.c b/libgcc/config/stormy16/cmpsi2.c new file mode 100644 index 0000000..fe32fda --- /dev/null +++ b/libgcc/config/stormy16/cmpsi2.c @@ -0,0 +1,2 @@ +#define XSTORMY16_CMPSI2 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/ctzhi2.c b/libgcc/config/stormy16/ctzhi2.c new file mode 100644 index 0000000..98ab76d --- /dev/null +++ b/libgcc/config/stormy16/ctzhi2.c @@ -0,0 +1,2 @@ +#define XSTORMY16_CTZHI2 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/divsi3.c b/libgcc/config/stormy16/divsi3.c new file mode 100644 index 0000000..0fa7534 --- /dev/null +++ b/libgcc/config/stormy16/divsi3.c @@ -0,0 +1,2 @@ +#define XSTORMY16_DIVSI3 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/ffshi2.c b/libgcc/config/stormy16/ffshi2.c new file mode 100644 index 0000000..a36dec8 --- /dev/null +++ b/libgcc/config/stormy16/ffshi2.c @@ -0,0 +1,2 @@ +#define XSTORMY16_FFSHI2 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/lib2funcs.c b/libgcc/config/stormy16/lib2funcs.c new file mode 100644 index 0000000..e3c1643 --- /dev/null +++ b/libgcc/config/stormy16/lib2funcs.c @@ -0,0 +1,357 @@ +/* This file contains 16-bit versions of some of the functions found in + libgcc2.c. Really libgcc ought to be moved out of the gcc directory + and into its own top level directory, and then split up into multiple + files. On this glorious day maybe this code can be integrated into + it too. */ + +/* Copyright (C) 2005, 2008, 2009, 2010 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "tconfig.h" +#include "tsystem.h" +#include "coretypes.h" +#include "tm.h" + +#ifdef HAVE_GAS_HIDDEN +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) +#else +#define ATTRIBUTE_HIDDEN +#endif + +#ifndef MIN_UNITS_PER_WORD +#define MIN_UNITS_PER_WORD UNITS_PER_WORD +#endif + +#ifndef LIBGCC2_UNITS_PER_WORD +# if MIN_UNITS_PER_WORD > 4 +# define LIBGCC2_UNITS_PER_WORD 8 +# elif (MIN_UNITS_PER_WORD > 2 \ + || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32)) +# define LIBGCC2_UNITS_PER_WORD 4 +# else +# define LIBGCC2_UNITS_PER_WORD MIN_UNITS_PER_WORD +# endif +#endif + +#define word_type Wtype + +#include "libgcc2.h" +#undef int + +/* These prototypes would normally live in libgcc2.h, but this can + only happen once the code below is integrated into libgcc2.c. */ + +extern USItype udivmodsi4 (USItype, USItype, word_type); +extern SItype __divsi3 (SItype, SItype); +extern SItype __modsi3 (SItype, SItype); +extern SItype __udivsi3 (SItype, SItype); +extern SItype __umodsi3 (SItype, SItype); +extern SItype __ashlsi3 (SItype, SItype); +extern SItype __ashrsi3 (SItype, SItype); +extern USItype __lshrsi3 (USItype, USItype); +extern int __popcounthi2 (UHWtype); +extern int __parityhi2 (UHWtype); +extern int __clzhi2 (UHWtype); +extern int __ctzhi2 (UHWtype); + + +#ifdef XSTORMY16_UDIVMODSI4 +USItype +udivmodsi4 (USItype num, USItype den, word_type modwanted) +{ + USItype bit = 1; + USItype res = 0; + + while (den < num && bit && !(den & (1L << 31))) + { + den <<= 1; + bit <<= 1; + } + while (bit) + { + if (num >= den) + { + num -= den; + res |= bit; + } + bit >>= 1; + den >>= 1; + } + + if (modwanted) + return num; + return res; +} +#endif + +#ifdef XSTORMY16_DIVSI3 +SItype +__divsi3 (SItype a, SItype b) +{ + word_type neg = 0; + SItype res; + + if (a < 0) + { + a = -a; + neg = !neg; + } + + if (b < 0) + { + b = -b; + neg = !neg; + } + + res = udivmodsi4 (a, b, 0); + + if (neg) + res = -res; + + return res; +} +#endif + +#ifdef XSTORMY16_MODSI3 +SItype +__modsi3 (SItype a, SItype b) +{ + word_type neg = 0; + SItype res; + + if (a < 0) + { + a = -a; + neg = 1; + } + + if (b < 0) + b = -b; + + res = udivmodsi4 (a, b, 1); + + if (neg) + res = -res; + + return res; +} +#endif + +#ifdef XSTORMY16_UDIVSI3 +SItype +__udivsi3 (SItype a, SItype b) +{ + return udivmodsi4 (a, b, 0); +} +#endif + +#ifdef XSTORMY16_UMODSI3 +SItype +__umodsi3 (SItype a, SItype b) +{ + return udivmodsi4 (a, b, 1); +} +#endif + +#ifdef XSTORMY16_ASHLSI3 +SItype +__ashlsi3 (SItype a, SItype b) +{ + word_type i; + + if (b & 16) + a <<= 16; + if (b & 8) + a <<= 8; + for (i = (b & 0x7); i > 0; --i) + a <<= 1; + return a; +} +#endif + +#ifdef XSTORMY16_ASHRSI3 +SItype +__ashrsi3 (SItype a, SItype b) +{ + word_type i; + + if (b & 16) + a >>= 16; + if (b & 8) + a >>= 8; + for (i = (b & 0x7); i > 0; --i) + a >>= 1; + return a; +} +#endif + +#ifdef XSTORMY16_LSHRSI3 +USItype +__lshrsi3 (USItype a, USItype b) +{ + word_type i; + + if (b & 16) + a >>= 16; + if (b & 8) + a >>= 8; + for (i = (b & 0x7); i > 0; --i) + a >>= 1; + return a; +} +#endif + +#ifdef XSTORMY16_POPCOUNTHI2 +/* Returns the number of set bits in X. + FIXME: The return type really should be "unsigned int" + but this is not how the builtin is prototyped. */ +int +__popcounthi2 (UHWtype x) +{ + int ret; + + ret = __popcount_tab [x & 0xff]; + ret += __popcount_tab [(x >> 8) & 0xff]; + + return ret; +} +#endif + +#ifdef XSTORMY16_PARITYHI2 +/* Returns the number of set bits in X, modulo 2. + FIXME: The return type really should be "unsigned int" + but this is not how the builtin is prototyped. */ + +int +__parityhi2 (UHWtype x) +{ + x ^= x >> 8; + x ^= x >> 4; + x &= 0xf; + return (0x6996 >> x) & 1; +} +#endif + +#ifdef XSTORMY16_CLZHI2 +/* Returns the number of zero-bits from the most significant bit to the + first nonzero bit in X. Returns 16 for X == 0. Implemented as a + simple for loop in order to save space by removing the need for + the __clz_tab array. + FIXME: The return type really should be "unsigned int" but this is + not how the builtin is prototyped. */ +#undef unsigned +int +__clzhi2 (UHWtype x) +{ + unsigned int i; + unsigned int c; + unsigned int value = x; + + for (c = 0, i = 1 << 15; i; i >>= 1, c++) + if (i & value) + break; + return c; +} +#endif + +#ifdef XSTORMY16_CTZHI2 +/* Returns the number of trailing zero bits in X. + FIXME: The return type really should be "signed int" since + ctz(0) returns -1, but this is not how the builtin is prototyped. */ + +int +__ctzhi2 (UHWtype x) +{ + /* This is cunning. It converts X into a number with only the one bit + set, the bit that was the least significant bit in X. From this we + can use the count_leading_zeros to compute the number of trailing + bits. */ + x &= - x; + + return 15 - __builtin_clz (x); +} +#endif + +#ifdef XSTORMY16_FFSHI2 +/* Returns one plus the index of the least significant 1-bit of X, + or if X is zero, returns zero. FIXME: The return type really + should be "unsigned int" but this is not how the builtin is + prototyped. */ + +int +__ffshi2 (UHWtype u) +{ + UHWtype count; + + if (u == 0) + return 0; + + return 16 - __builtin_clz (u & - u); +} +#endif + +#ifdef XSTORMY16_UCMPSI2 +/* Performs an unsigned comparison of two 32-bit values: A and B. + If A is less than B, then 0 is returned. If A is greater than B, + then 2 is returned. Otherwise A and B are equal and 1 is returned. */ + +word_type +__ucmpsi2 (USItype a, USItype b) +{ + word_type hi_a = (a >> 16); + word_type hi_b = (b >> 16); + + if (hi_a == hi_b) + { + word_type low_a = (a & 0xffff); + word_type low_b = (b & 0xffff); + + return low_a < low_b ? 0 : (low_a > low_b ? 2 : 1); + } + + return hi_a < hi_b ? 0 : 2; +} +#endif + +#ifdef XSTORMY16_CMPSI2 +/* Performs an signed comparison of two 32-bit values: A and B. + If A is less than B, then 0 is returned. If A is greater than B, + then 2 is returned. Otherwise A and B are equal and 1 is returned. */ + +word_type +__cmpsi2 (SItype a, SItype b) +{ + word_type hi_a = (a >> 16); + word_type hi_b = (b >> 16); + + if (hi_a == hi_b) + { + word_type low_a = (a & 0xffff); + word_type low_b = (b & 0xffff); + + return low_a < low_b ? 0 : (low_a > low_b ? 2 : 1); + } + + return hi_a < hi_b ? 0 : 2; +} +#endif diff --git a/libgcc/config/stormy16/lshrsi3.c b/libgcc/config/stormy16/lshrsi3.c new file mode 100644 index 0000000..13903d3 --- /dev/null +++ b/libgcc/config/stormy16/lshrsi3.c @@ -0,0 +1,2 @@ +#define XSTORMY16_LSHRSI3 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/modsi3.c b/libgcc/config/stormy16/modsi3.c new file mode 100644 index 0000000..c63e890 --- /dev/null +++ b/libgcc/config/stormy16/modsi3.c @@ -0,0 +1,2 @@ +#define XSTORMY16_MODSI3 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/parityhi2.c b/libgcc/config/stormy16/parityhi2.c new file mode 100644 index 0000000..4be7fbf --- /dev/null +++ b/libgcc/config/stormy16/parityhi2.c @@ -0,0 +1,2 @@ +#define XSTORMY16_PARITYHI2 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/popcounthi2.c b/libgcc/config/stormy16/popcounthi2.c new file mode 100644 index 0000000..30bf095 --- /dev/null +++ b/libgcc/config/stormy16/popcounthi2.c @@ -0,0 +1,2 @@ +#define XSTORMY16_POPCOUNTHI2 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/t-stormy16 b/libgcc/config/stormy16/t-stormy16 new file mode 100644 index 0000000..8726a3d --- /dev/null +++ b/libgcc/config/stormy16/t-stormy16 @@ -0,0 +1,39 @@ +# -*- makefile -*- +# +# Copyright (C) 2001, 2004, 2010, 2011 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# SImode arithmetic and logical routines, HImode bit counting routines. +LIB2ADD = \ + $(srcdir)/config/stormy16/udivmodsi4.c \ + $(srcdir)/config/stormy16/divsi3.c \ + $(srcdir)/config/stormy16/modsi3.c \ + $(srcdir)/config/stormy16/udivsi3.c \ + $(srcdir)/config/stormy16/umodsi3.c \ + $(srcdir)/config/stormy16/ashlsi3.c \ + $(srcdir)/config/stormy16/ashrsi3.c \ + $(srcdir)/config/stormy16/lshrsi3.c \ + $(srcdir)/config/stormy16/popcounthi2.c \ + $(srcdir)/config/stormy16/parityhi2.c \ + $(srcdir)/config/stormy16/clzhi2.c \ + $(srcdir)/config/stormy16/ctzhi2.c \ + $(srcdir)/config/stormy16/ffshi2.c \ + $(srcdir)/config/stormy16/cmpsi2.c \ + $(srcdir)/config/stormy16/ucmpsi2.c + +HOST_LIBGCC2_CFLAGS = -O2 diff --git a/libgcc/config/stormy16/ucmpsi2.c b/libgcc/config/stormy16/ucmpsi2.c new file mode 100644 index 0000000..ee327b1 --- /dev/null +++ b/libgcc/config/stormy16/ucmpsi2.c @@ -0,0 +1,2 @@ +#define XSTORMY16_UCMPSI2 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/udivmodsi4.c b/libgcc/config/stormy16/udivmodsi4.c new file mode 100644 index 0000000..5fdd0f9 --- /dev/null +++ b/libgcc/config/stormy16/udivmodsi4.c @@ -0,0 +1,2 @@ +#define XSTORMY16_UDIVMODSI4 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/udivsi3.c b/libgcc/config/stormy16/udivsi3.c new file mode 100644 index 0000000..ad12bd8 --- /dev/null +++ b/libgcc/config/stormy16/udivsi3.c @@ -0,0 +1,2 @@ +#define XSTORMY16_UDIVSI3 +#include "lib2funcs.c" diff --git a/libgcc/config/stormy16/umodsi3.c b/libgcc/config/stormy16/umodsi3.c new file mode 100644 index 0000000..eeec67f --- /dev/null +++ b/libgcc/config/stormy16/umodsi3.c @@ -0,0 +1,2 @@ +#define XSTORMY16_UMODSI3 +#include "lib2funcs.c" diff --git a/libgcc/config/t-crtstuff-pic b/libgcc/config/t-crtstuff-pic index 55e5fc1..4cda4c9 100644 --- a/libgcc/config/t-crtstuff-pic +++ b/libgcc/config/t-crtstuff-pic @@ -1,2 +1,2 @@ # Compile crtbeginS.o and crtendS.o with pic. -CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC +CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) $(PICFLAG) diff --git a/libgcc/config/t-darwin b/libgcc/config/t-darwin index 311b7e2..e32127e 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 $< +# -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 +# works around this by not having any temporary file names. +HOST_LIBGCC2_CFLAGS += -pipe + # Use unwind-dw2-fde-darwin LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/config/unwind-dw2-fde-darwin.c \ $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c diff --git a/libgcc/config/t-freebsd-thread b/libgcc/config/t-freebsd-thread new file mode 100644 index 0000000..2948dc1 --- /dev/null +++ b/libgcc/config/t-freebsd-thread @@ -0,0 +1,2 @@ +# This is currently needed to compile libgcc2 for threads support +HOST_LIBGCC2_CFLAGS += -pthread diff --git a/libgcc/config/t-libgcc-pic b/libgcc/config/t-libgcc-pic new file mode 100644 index 0000000..0eea16e --- /dev/null +++ b/libgcc/config/t-libgcc-pic @@ -0,0 +1,2 @@ +# Compile libgcc2.a with pic. +HOST_LIBGCC2_CFLAGS += $(PICFLAG) diff --git a/libgcc/config/t-libunwind b/libgcc/config/t-libunwind index 135cbe1..5244928 100644 --- a/libgcc/config/t-libunwind +++ b/libgcc/config/t-libunwind @@ -1,5 +1,7 @@ # Use the system libunwind library. +HOST_LIBGCC2_CFLAGS += -DUSE_GAS_SYMVER + LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c \ $(srcdir)/unwind-compat.c $(srcdir)/unwind-dw2-fde-compat.c LIB2ADDEHSTATIC = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c diff --git a/libgcc/config/t-openbsd-thread b/libgcc/config/t-openbsd-thread new file mode 100644 index 0000000..17d17ed --- /dev/null +++ b/libgcc/config/t-openbsd-thread @@ -0,0 +1,3 @@ +# This is currently needed to compile libgcc2 for threads support +HOST_LIBGCC2_CFLAGS=-pthread + diff --git a/libgcc/config/t-sol2 b/libgcc/config/t-sol2 index ab34a75..09bbdf6 100644 --- a/libgcc/config/t-sol2 +++ b/libgcc/config/t-sol2 @@ -31,5 +31,3 @@ crti.o: $(srcdir)/config/$(cpu_type)/sol2-ci.S $(crt_compile) -c $< crtn.o: $(srcdir)/config/$(cpu_type)/sol2-cn.S $(crt_compile) -c $< - -HOST_LIBGCC2_CFLAGS = -fPIC diff --git a/libgcc/config/t-vxworks b/libgcc/config/t-vxworks new file mode 100644 index 0000000..ab8f014 --- /dev/null +++ b/libgcc/config/t-vxworks @@ -0,0 +1,18 @@ +# FIXME: Need to specify the next two? +# No special flags needed for libgcc.a +HOST_LIBGCC2_CFLAGS = + +# Don't build libgcc.a with debug info +LIBGCC2_DEBUG_CFLAGS = + +# Extra libgcc2 modules used by gthr-vxworks.h functions +LIB2ADD = $(srcdir)/config/vxlib.c $(srcdir)/config/vxlib-tls.c + +# This ensures that the correct target headers are used; some +# VxWorks system headers have names that collide with GCC's +# internal (host) headers, e.g. regs.h. +LIBGCC2_INCLUDES = -nostdinc -I \ + `case "/$$(MULTIDIR)" in \ + */mrtp*) echo $(WIND_USR)/h ;; \ + *) echo $(WIND_BASE)/target/h ;; \ + esac` diff --git a/libgcc/config/vxlib-tls.c b/libgcc/config/vxlib-tls.c new file mode 100644 index 0000000..c469676 --- /dev/null +++ b/libgcc/config/vxlib-tls.c @@ -0,0 +1,362 @@ +/* Copyright (C) 2002, 2003, 2004, 2005, 2009 Free Software Foundation, Inc. + Contributed by Zack Weinberg <zack@codesourcery.com> + +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/>. */ + +/* Threads compatibility routines for libgcc2 for VxWorks. + These are out-of-line routines called from gthr-vxworks.h. + + This file provides the TLS related support routines, calling specific + VxWorks kernel entry points for this purpose. The base VxWorks 5.x kernels + don't feature these entry points, and we provide gthr_supp_vxw_5x.c as an + option to fill this gap. Asking users to rebuild a kernel is not to be + taken lightly, still, so we have isolated these routines from the rest of + vxlib to ensure that the kernel dependencies are only dragged when really + necessary. */ + +#include "tconfig.h" +#include "tsystem.h" +#include "gthr.h" + +#if defined(__GTHREADS) +#include <vxWorks.h> +#ifndef __RTP__ +#include <vxLib.h> +#endif +#include <taskLib.h> +#ifndef __RTP__ +#include <taskHookLib.h> +#else +# include <errno.h> +#endif + +/* Thread-local storage. + + We reserve a field in the TCB to point to a dynamically allocated + array which is used to store TLS values. A TLS key is simply an + offset in this array. The exact location of the TCB field is not + known to this code nor to vxlib.c -- all access to it indirects + through the routines __gthread_get_tls_data and + __gthread_set_tls_data, which are provided by the VxWorks kernel. + + There is also a global array which records which keys are valid and + which have destructors. + + A task delete hook is installed to execute key destructors. The + routines __gthread_enter_tls_dtor_context and + __gthread_leave_tls_dtor_context, which are also provided by the + kernel, ensure that it is safe to call free() on memory allocated + by the task being deleted. (This is a no-op on VxWorks 5, but + a major undertaking on AE.) + + The task delete hook is only installed when at least one thread + has TLS data. This is a necessary precaution, to allow this module + to be unloaded - a module with a hook can not be removed. + + Since this interface is used to allocate only a small number of + keys, the table size is small and static, which simplifies the + code quite a bit. Revisit this if and when it becomes necessary. */ + +#define MAX_KEYS 4 + +/* This is the structure pointed to by the pointer returned + by __gthread_get_tls_data. */ +struct tls_data +{ + int *owner; + void *values[MAX_KEYS]; + unsigned int generation[MAX_KEYS]; +}; + +/* To make sure we only delete TLS data associated with this object, + include a pointer to a local variable in the TLS data object. */ +static int self_owner; + +/* Flag to check whether the delete hook is installed. Once installed + it is only removed when unloading this module. */ +static volatile int delete_hook_installed; + +/* kernel provided routines */ +extern void *__gthread_get_tls_data (void); +extern void __gthread_set_tls_data (void *data); + +extern void __gthread_enter_tls_dtor_context (void); +extern void __gthread_leave_tls_dtor_context (void); + + +/* This is a global structure which records all of the active keys. + + A key is potentially valid (i.e. has been handed out by + __gthread_key_create) iff its generation count in this structure is + even. In that case, the matching entry in the dtors array is a + routine to be called when a thread terminates with a valid, + non-NULL specific value for that key. + + A key is actually valid in a thread T iff the generation count + stored in this structure is equal to the generation count stored in + T's specific-value structure. */ + +typedef void (*tls_dtor) (void *); + +struct tls_keys +{ + tls_dtor dtor[MAX_KEYS]; + unsigned int generation[MAX_KEYS]; +}; + +#define KEY_VALID_P(key) !(tls_keys.generation[key] & 1) + +/* Note: if MAX_KEYS is increased, this initializer must be updated + to match. All the generation counts begin at 1, which means no + key is valid. */ +static struct tls_keys tls_keys = +{ + { 0, 0, 0, 0 }, + { 1, 1, 1, 1 } +}; + +/* This lock protects the tls_keys structure. */ +static __gthread_mutex_t tls_lock; + +static __gthread_once_t tls_init_guard = __GTHREAD_ONCE_INIT; + +/* Internal routines. */ + +/* The task TCB has just been deleted. Call the destructor + function for each TLS key that has both a destructor and + a non-NULL specific value in this thread. + + This routine does not need to take tls_lock; the generation + count protects us from calling a stale destructor. It does + need to read tls_keys.dtor[key] atomically. */ + +static void +tls_delete_hook (void *tcb ATTRIBUTE_UNUSED) +{ + struct tls_data *data; + __gthread_key_t key; + +#ifdef __RTP__ + data = __gthread_get_tls_data (); +#else + /* In kernel mode, we can be called in the context of the thread + doing the killing, so must use the TCB to determine the data of + the thread being killed. */ + data = __gthread_get_tsd_data (tcb); +#endif + + if (data && data->owner == &self_owner) + { +#ifdef __RTP__ + __gthread_enter_tls_dtor_context (); +#else + __gthread_enter_tsd_dtor_context (tcb); +#endif + for (key = 0; key < MAX_KEYS; key++) + { + if (data->generation[key] == tls_keys.generation[key]) + { + tls_dtor dtor = tls_keys.dtor[key]; + + if (dtor) + dtor (data->values[key]); + } + } + free (data); +#ifdef __RTP__ + __gthread_leave_tls_dtor_context (); +#else + __gthread_leave_tsd_dtor_context (); +#endif + +#ifdef __RTP__ + __gthread_set_tls_data (0); +#else + __gthread_set_tsd_data (tcb, 0); +#endif + } +} + +/* Initialize global data used by the TLS system. */ +static void +tls_init (void) +{ + __GTHREAD_MUTEX_INIT_FUNCTION (&tls_lock); +} + +static void tls_destructor (void) __attribute__ ((destructor)); +static void +tls_destructor (void) +{ +#ifdef __RTP__ + /* All threads but this one should have exited by now. */ + tls_delete_hook (NULL); +#endif + /* Unregister the hook. */ + if (delete_hook_installed) + taskDeleteHookDelete ((FUNCPTR)tls_delete_hook); + + if (tls_init_guard.done && __gthread_mutex_lock (&tls_lock) != ERROR) + semDelete (tls_lock); +} + +/* External interface */ + +/* Store in KEYP a value which can be passed to __gthread_setspecific/ + __gthread_getspecific to store and retrieve a value which is + specific to each calling thread. If DTOR is not NULL, it will be + called when a thread terminates with a non-NULL specific value for + this key, with the value as its sole argument. */ + +int +__gthread_key_create (__gthread_key_t *keyp, tls_dtor dtor) +{ + __gthread_key_t key; + + __gthread_once (&tls_init_guard, tls_init); + + if (__gthread_mutex_lock (&tls_lock) == ERROR) + return errno; + + for (key = 0; key < MAX_KEYS; key++) + if (!KEY_VALID_P (key)) + goto found_slot; + + /* no room */ + __gthread_mutex_unlock (&tls_lock); + return EAGAIN; + + found_slot: + tls_keys.generation[key]++; /* making it even */ + tls_keys.dtor[key] = dtor; + *keyp = key; + __gthread_mutex_unlock (&tls_lock); + return 0; +} + +/* Invalidate KEY; it can no longer be used as an argument to + setspecific/getspecific. Note that this does NOT call destructor + functions for any live values for this key. */ +int +__gthread_key_delete (__gthread_key_t key) +{ + if (key >= MAX_KEYS) + return EINVAL; + + __gthread_once (&tls_init_guard, tls_init); + + if (__gthread_mutex_lock (&tls_lock) == ERROR) + return errno; + + if (!KEY_VALID_P (key)) + { + __gthread_mutex_unlock (&tls_lock); + return EINVAL; + } + + tls_keys.generation[key]++; /* making it odd */ + tls_keys.dtor[key] = 0; + + __gthread_mutex_unlock (&tls_lock); + return 0; +} + +/* Retrieve the thread-specific value for KEY. If it has never been + set in this thread, or KEY is invalid, returns NULL. + + It does not matter if this function races with key_create or + key_delete; the worst that can happen is you get a value other than + the one that a serialized implementation would have provided. */ + +void * +__gthread_getspecific (__gthread_key_t key) +{ + struct tls_data *data; + + if (key >= MAX_KEYS) + return 0; + + data = __gthread_get_tls_data (); + + if (!data) + return 0; + + if (data->generation[key] != tls_keys.generation[key]) + return 0; + + return data->values[key]; +} + +/* Set the thread-specific value for KEY. If KEY is invalid, or + memory allocation fails, returns -1, otherwise 0. + + The generation count protects this function against races with + key_create/key_delete; the worst thing that can happen is that a + value is successfully stored into a dead generation (and then + immediately becomes invalid). However, we do have to make sure + to read tls_keys.generation[key] atomically. */ + +int +__gthread_setspecific (__gthread_key_t key, void *value) +{ + struct tls_data *data; + unsigned int generation; + + if (key >= MAX_KEYS) + return EINVAL; + + data = __gthread_get_tls_data (); + if (!data) + { + if (!delete_hook_installed) + { + /* Install the delete hook. */ + if (__gthread_mutex_lock (&tls_lock) == ERROR) + return ENOMEM; + if (!delete_hook_installed) + { + taskDeleteHookAdd ((FUNCPTR)tls_delete_hook); + delete_hook_installed = 1; + } + __gthread_mutex_unlock (&tls_lock); + } + + data = malloc (sizeof (struct tls_data)); + if (!data) + return ENOMEM; + + memset (data, 0, sizeof (struct tls_data)); + data->owner = &self_owner; + __gthread_set_tls_data (data); + } + + generation = tls_keys.generation[key]; + + if (generation & 1) + return EINVAL; + + data->generation[key] = generation; + data->values[key] = value; + + return 0; +} +#endif /* __GTHREADS */ diff --git a/libgcc/config/vxlib.c b/libgcc/config/vxlib.c new file mode 100644 index 0000000..0ff996c --- /dev/null +++ b/libgcc/config/vxlib.c @@ -0,0 +1,95 @@ +/* Copyright (C) 2002, 2003, 2004, 2005, 2009 Free Software Foundation, Inc. + Contributed by Zack Weinberg <zack@codesourcery.com> + +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/>. */ + +/* Threads compatibility routines for libgcc2 for VxWorks. + These are out-of-line routines called from gthr-vxworks.h. */ + +#include "tconfig.h" +#include "tsystem.h" +#include "gthr.h" + +#if defined(__GTHREADS) +#include <vxWorks.h> +#ifndef __RTP__ +#include <vxLib.h> +#endif +#include <taskLib.h> +#ifndef __RTP__ +#include <taskHookLib.h> +#else +# include <errno.h> +#endif + +/* Init-once operation. + + This would be a clone of the implementation from gthr-solaris.h, + except that we have a bootstrap problem - the whole point of this + exercise is to prevent double initialization, but if two threads + are racing with each other, once->mutex is liable to be initialized + by both. Then each thread will lock its own mutex, and proceed to + call the initialization routine. + + So instead we use a bare atomic primitive (vxTas()) to handle + mutual exclusion. Threads losing the race then busy-wait, calling + taskDelay() to yield the processor, until the initialization is + completed. Inefficient, but reliable. */ + +int +__gthread_once (__gthread_once_t *guard, void (*func)(void)) +{ + if (guard->done) + return 0; + +#ifdef __RTP__ + __gthread_lock_library (); +#else + while (!vxTas ((void *)&guard->busy)) + { +#ifdef __PPC__ + /* This can happen on powerpc, which is using all 32 bits + of the gthread_once_t structure. */ + if (guard->done) + return; +#endif + taskDelay (1); + } +#endif + + /* Only one thread at a time gets here. Check ->done again, then + go ahead and call func() if no one has done it yet. */ + if (!guard->done) + { + func (); + guard->done = 1; + } + +#ifdef __RTP__ + __gthread_unlock_library (); +#else + guard->busy = 0; +#endif + return 0; +} + +#endif /* __GTHREADS */ diff --git a/libgcc/config/xtensa/lib2funcs.S b/libgcc/config/xtensa/lib2funcs.S new file mode 100644 index 0000000..65134e2 --- /dev/null +++ b/libgcc/config/xtensa/lib2funcs.S @@ -0,0 +1,186 @@ +/* Assembly functions for libgcc2. + Copyright (C) 2001, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica. + +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 "xtensa-config.h" + +/* __xtensa_libgcc_window_spill: This function flushes out all but the + current register window. This is used to set up the stack so that + arbitrary frames can be accessed. */ + + .align 4 + .global __xtensa_libgcc_window_spill + .type __xtensa_libgcc_window_spill,@function +__xtensa_libgcc_window_spill: + entry sp, 32 + movi a2, 0 + syscall + retw + .size __xtensa_libgcc_window_spill, .-__xtensa_libgcc_window_spill + + +/* __xtensa_nonlocal_goto: This code does all the hard work of a + nonlocal goto on Xtensa. It is here in the library to avoid the + code size bloat of generating it in-line. There are two + arguments: + + a2 = frame pointer for the procedure containing the label + a3 = goto handler address + + This function never returns to its caller but instead goes directly + to the address of the specified goto handler. */ + + .align 4 + .global __xtensa_nonlocal_goto + .type __xtensa_nonlocal_goto,@function +__xtensa_nonlocal_goto: + entry sp, 32 + + /* Flush registers. */ + mov a5, a2 + movi a2, 0 + syscall + mov a2, a5 + + /* Because the save area for a0-a3 is stored one frame below + the one identified by a2, the only way to restore those + registers is to unwind the stack. If alloca() were never + called, we could just unwind until finding the sp value + matching a2. However, a2 is a frame pointer, not a stack + pointer, and may not be encountered during the unwinding. + The solution is to unwind until going _past_ the value + given by a2. This involves keeping three stack pointer + values during the unwinding: + + next = sp of frame N-1 + cur = sp of frame N + prev = sp of frame N+1 + + When next > a2, the desired save area is stored relative + to prev. At this point, cur will be the same as a2 + except in the alloca() case. + + Besides finding the values to be restored to a0-a3, we also + need to find the current window size for the target + function. This can be extracted from the high bits of the + return address, initially in a0. As the unwinding + proceeds, the window size is taken from the value of a0 + saved _two_ frames below the current frame. */ + + addi a5, sp, -16 /* a5 = prev - save area */ + l32i a6, a5, 4 + addi a6, a6, -16 /* a6 = cur - save area */ + mov a8, a0 /* a8 = return address (for window size) */ + j .Lfirstframe + +.Lnextframe: + l32i a8, a5, 0 /* next return address (for window size) */ + mov a5, a6 /* advance prev */ + addi a6, a7, -16 /* advance cur */ +.Lfirstframe: + l32i a7, a6, 4 /* a7 = next */ + bgeu a2, a7, .Lnextframe + + /* At this point, prev (a5) points to the save area with the saved + values of a0-a3. Copy those values into the save area at the + current sp so they will be reloaded when the return from this + function underflows. We don't have to worry about exceptions + while updating the current save area, because the windows have + already been flushed. */ + + addi a4, sp, -16 /* a4 = save area of this function */ + l32i a6, a5, 0 + l32i a7, a5, 4 + s32i a6, a4, 0 + s32i a7, a4, 4 + l32i a6, a5, 8 + l32i a7, a5, 12 + s32i a6, a4, 8 + s32i a7, a4, 12 + + /* Set return address to goto handler. Use the window size bits + from the return address two frames below the target. */ + extui a8, a8, 30, 2 /* get window size from return addr. */ + slli a3, a3, 2 /* get goto handler addr. << 2 */ + ssai 2 + src a0, a8, a3 /* combine them with a funnel shift */ + + retw + .size __xtensa_nonlocal_goto, .-__xtensa_nonlocal_goto + + +/* __xtensa_sync_caches: This function is called after writing a trampoline + on the stack to force all the data writes to memory and invalidate the + instruction cache. a2 is the address of the new trampoline. + + After the trampoline data is written out, it must be flushed out of + the data cache into memory. We use DHWB in case we have a writeback + cache. At least one DHWB instruction is needed for each data cache + line which may be touched by the trampoline. An ISYNC instruction + must follow the DHWBs. + + We have to flush the i-cache to make sure that the new values get used. + At least one IHI instruction is needed for each i-cache line which may + be touched by the trampoline. An ISYNC instruction is also needed to + make sure that the modified instructions are loaded into the instruction + fetch buffer. */ + +/* Use the maximum trampoline size. Flushing a bit extra is OK. */ +#define TRAMPOLINE_SIZE 60 + + .text + .align 4 + .global __xtensa_sync_caches + .type __xtensa_sync_caches,@function +__xtensa_sync_caches: + entry sp, 32 +#if XCHAL_DCACHE_SIZE > 0 + /* Flush the trampoline from the data cache. */ + extui a4, a2, 0, XCHAL_DCACHE_LINEWIDTH + addi a4, a4, TRAMPOLINE_SIZE + addi a4, a4, (1 << XCHAL_DCACHE_LINEWIDTH) - 1 + srli a4, a4, XCHAL_DCACHE_LINEWIDTH + mov a3, a2 +.Ldcache_loop: + dhwb a3, 0 + addi a3, a3, (1 << XCHAL_DCACHE_LINEWIDTH) + addi a4, a4, -1 + bnez a4, .Ldcache_loop + isync +#endif +#if XCHAL_ICACHE_SIZE > 0 + /* Invalidate the corresponding lines in the instruction cache. */ + extui a4, a2, 0, XCHAL_ICACHE_LINEWIDTH + addi a4, a4, TRAMPOLINE_SIZE + addi a4, a4, (1 << XCHAL_ICACHE_LINEWIDTH) - 1 + srli a4, a4, XCHAL_ICACHE_LINEWIDTH +.Licache_loop: + ihi a2, 0 + addi a2, a2, (1 << XCHAL_ICACHE_LINEWIDTH) + addi a4, a4, -1 + bnez a4, .Licache_loop +#endif + isync + retw + .size __xtensa_sync_caches, .-__xtensa_sync_caches diff --git a/libgcc/config/xtensa/t-elf b/libgcc/config/xtensa/t-elf index dffcbc8..59d5121 100644 --- a/libgcc/config/xtensa/t-elf +++ b/libgcc/config/xtensa/t-elf @@ -1,3 +1,5 @@ # Build CRT files and libgcc with the "longcalls" option CRTSTUFF_T_CFLAGS += -mlongcalls CRTSTUFF_T_CFLAGS_S += -mlongcalls + +HOST_LIBGCC2_CFLAGS += -mlongcalls diff --git a/libgcc/config/xtensa/t-xtensa b/libgcc/config/xtensa/t-xtensa index 5bcc094..27399e6 100644 --- a/libgcc/config/xtensa/t-xtensa +++ b/libgcc/config/xtensa/t-xtensa @@ -10,5 +10,7 @@ LIB1ASMFUNCS = _mulsi3 _divsi3 _modsi3 _udivsi3 _umodsi3 \ _floatdidf _floatundidf \ _truncdfsf2 _extendsfdf2 +LIB2ADD = $(srcdir)/config/xtensa/lib2funcs.S + LIB2ADDEH = $(srcdir)/config/xtensa/unwind-dw2-xtensa.c \ $(srcdir)/unwind-dw2-fde.c $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c diff --git a/libgcc/configure b/libgcc/configure index 0506dcf..192db62 100644 --- a/libgcc/configure +++ b/libgcc/configure @@ -627,6 +627,13 @@ build_subdir build_libsubdir target_noncanonical host_noncanonical +AWK +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +MAINT +slibdir +PICFLAG host_os host_vendor host_cpu @@ -635,12 +642,6 @@ build_os build_vendor build_cpu build -AWK -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -MAINT -slibdir enable_shared libgcc_topdir target_alias @@ -2197,6 +2198,159 @@ fi +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + + + # FIXME: Do we need something for CFLAGS below? + +case "${host}" in + # PIC is the default on some targets or must not be used. + *-*-darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + PICFLAG=-fno-common + ;; + alpha*-dec-osf5*) + # PIC is the default. + ;; + hppa*64*-*-hpux*) + # PIC is the default for 64-bit PA HP-UX. + ;; + i3456786-*-cygwin* | i3456786-*-mingw* | x86_64-*-mingw*) + ;; + i3456786-*-interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + i3456786-*-nto-qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + PICFLAG='-fPIC -shared' + ;; + i3456786-pc-msdosdjgpp*) + # DJGPP does not support shared libraries at all. + ;; + ia64*-*-hpux*) + # On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + # FIXME: Still in gcc 4.7? + PICFLAG=-fPIC + ;; + mips-sgi-irix6*) + # PIC is the default. + ;; + rs6000-ibm-aix* | powerpc-ibm-aix*) + # All AIX code is PIC. + ;; + + # Some targets support both -fPIC and -fpic, but prefer the latter. + # FIXME: Why? + i3456786-*-* | x86_64-*-*) + PICFLAG=-fpic + ;; + m68k-*-*) + PICFLAG=-fpic + ;; + s390*-*-*) + PICFLAG=-fpic + ;; + # FIXME: Override -fPIC default in libgcc only? + sh-*-linux* | sh2346lbe*-*-linux*) + PICFLAG=-fpic + ;; + # FIXME: Simplify to sh*-*-netbsd*? + sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \ + sh64-*-netbsd* | sh64l*-*-netbsd*) + PICFLAG=-fpic + ;; + sparc*-*-*) + # FIXME: This could be done everywhere -fpic and -fPIC differ. + case "${CFLAGS}" in + *-fpic*) + PICFLAG=-fpic + ;; + *) + PICFLAG=-fPIC + ;; + esac ;; + # Default to -fPIC unless specified otherwise. + *) + PICFLAG=-fPIC + ;; +esac + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-version-specific-runtime-libs" >&5 $as_echo_n "checking for --enable-version-specific-runtime-libs... " >&6; } # Check whether --enable-version-specific-runtime-libs was given. @@ -2385,76 +2539,6 @@ case ${AWK} in "") as_fn_error "can't build without awk, bailing out" "$LINENO" 5 ;; esac -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if test "${ac_cv_build+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if test "${ac_cv_host+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - case ${build_alias} in "") build_noncanonical=${build} ;; diff --git a/libgcc/configure.ac b/libgcc/configure.ac index b40e6d7..0aeede7 100644 --- a/libgcc/configure.ac +++ b/libgcc/configure.ac @@ -6,6 +6,7 @@ sinclude(../config/acx.m4) sinclude(../config/no-executables.m4) sinclude(../config/lib-ld.m4) sinclude(../config/override.m4) +sinclude(../config/picflag.m4) sinclude(../config/dfp.m4) sinclude(../config/unwind_ipinfo.m4) @@ -58,6 +59,9 @@ AC_ARG_ENABLE(shared, ], [enable_shared=yes]) AC_SUBST(enable_shared) +GCC_PICFLAG +AC_SUBST(PICFLAG) + AC_MSG_CHECKING([for --enable-version-specific-runtime-libs]) AC_ARG_ENABLE(version-specific-runtime-libs, [ --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory ], diff --git a/libgcc/divmod.c b/libgcc/divmod.c new file mode 100644 index 0000000..c227b99 --- /dev/null +++ b/libgcc/divmod.c @@ -0,0 +1,73 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +long udivmodsi4 (); + +long +__divsi3 (long a, long b) +{ + int neg = 0; + long res; + + if (a < 0) + { + a = -a; + neg = !neg; + } + + if (b < 0) + { + b = -b; + neg = !neg; + } + + res = udivmodsi4 (a, b, 0); + + if (neg) + res = -res; + + return res; +} + +long +__modsi3 (long a, long b) +{ + int neg = 0; + long res; + + if (a < 0) + { + a = -a; + neg = 1; + } + + if (b < 0) + b = -b; + + res = udivmodsi4 (a, b, 1); + + if (neg) + res = -res; + + return res; +} diff --git a/libgcc/floatunsidf.c b/libgcc/floatunsidf.c new file mode 100644 index 0000000..ff28112 --- /dev/null +++ b/libgcc/floatunsidf.c @@ -0,0 +1,15 @@ +/* Public domain. */ +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef float DFtype __attribute__ ((mode (DF))); + +DFtype +__floatunsidf (USItype u) +{ + SItype s = (SItype) u; + DFtype r = (DFtype) s; + if (s < 0) + r += (DFtype)2.0 * (DFtype) ((USItype) 1 + << (sizeof (USItype) * __CHAR_BIT__ - 1)); + return r; +} diff --git a/libgcc/floatunsisf.c b/libgcc/floatunsisf.c new file mode 100644 index 0000000..11d4aa7 --- /dev/null +++ b/libgcc/floatunsisf.c @@ -0,0 +1,18 @@ +/* Public domain. */ +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef float SFtype __attribute__ ((mode (SF))); + +SFtype +__floatunsisf (USItype u) +{ + SItype s = (SItype) u; + if (s < 0) + { + /* As in expand_float, compute (u & 1) | (u >> 1) to ensure + correct rounding if a nonzero bit is shifted out. */ + return (SFtype) 2.0 * (SFtype) (SItype) ((u & 1) | (u >> 1)); + } + else + return (SFtype) s; +} diff --git a/libgcc/floatunsitf.c b/libgcc/floatunsitf.c new file mode 100644 index 0000000..955d676 --- /dev/null +++ b/libgcc/floatunsitf.c @@ -0,0 +1,15 @@ +/* Public domain. */ +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef float TFtype __attribute__ ((mode (TF))); + +TFtype +__floatunsitf (USItype u) +{ + SItype s = (SItype) u; + TFtype r = (TFtype) s; + if (s < 0) + r += (TFtype)2.0 * (TFtype) ((USItype) 1 + << (sizeof (USItype) * __CHAR_BIT__ - 1)); + return r; +} diff --git a/libgcc/floatunsixf.c b/libgcc/floatunsixf.c new file mode 100644 index 0000000..5251168 --- /dev/null +++ b/libgcc/floatunsixf.c @@ -0,0 +1,15 @@ +/* Public domain. */ +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef float XFtype __attribute__ ((mode (XF))); + +XFtype +__floatunsixf (USItype u) +{ + SItype s = (SItype) u; + XFtype r = (XFtype) s; + if (s < 0) + r += (XFtype)2.0 * (XFtype) ((USItype) 1 + << (sizeof (USItype) * __CHAR_BIT__ - 1)); + return r; +} diff --git a/libgcc/gbl-ctors.h b/libgcc/gbl-ctors.h new file mode 100644 index 0000000..ac4faae --- /dev/null +++ b/libgcc/gbl-ctors.h @@ -0,0 +1,87 @@ +/* Definitions relating to the special __do_global_init function used + for getting g++ file-scope static objects constructed. This file + will get included either by libgcc2.c (for systems that don't support + a .init section) or by crtstuff.c (for those that do). + Copyright (C) 1991, 1995, 1996, 1998, 1999, 2000, 2003, 2009 + Free Software Foundation, Inc. + Contributed by Ron Guilmette (rfg@segfault.us.com) + +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/>. */ + +/* This file contains definitions and declarations of things + relating to the normal start-up-time invocation of C++ + file-scope static object constructors. These declarations + and definitions are used by *both* libgcc2.c and by crtstuff.c. + + Note that this file should only be compiled with GCC. +*/ + +#ifndef GCC_GBL_CTORS_H +#define GCC_GBL_CTORS_H + +/* Declare a pointer to void function type. */ + +typedef void (*func_ptr) (void); + +/* Declare the set of symbols use as begin and end markers for the lists + of global object constructors and global object destructors. */ + +extern func_ptr __CTOR_LIST__[]; +extern func_ptr __DTOR_LIST__[]; + +/* Declare the routine which needs to get invoked at program start time. */ + +extern void __do_global_ctors (void); + +/* Declare the routine which needs to get invoked at program exit time. */ + +extern void __do_global_dtors (void); + +/* Define a macro with the code which needs to be executed at program + start-up time. This macro is used in two places in crtstuff.c (for + systems which support a .init section) and in one place in libgcc2.c + (for those system which do *not* support a .init section). For all + three places where this code might appear, it must be identical, so + we define it once here as a macro to avoid various instances getting + out-of-sync with one another. */ + +/* Some systems place the number of pointers + in the first word of the table. + On other systems, that word is -1. + In all cases, the table is null-terminated. + If the length is not recorded, count up to the null. */ + +/* Some systems use a different strategy for finding the ctors. + For example, svr3. */ +#ifndef DO_GLOBAL_CTORS_BODY +#define DO_GLOBAL_CTORS_BODY \ +do { \ + __SIZE_TYPE__ nptrs = (__SIZE_TYPE__) __CTOR_LIST__[0]; \ + unsigned i; \ + if (nptrs == (__SIZE_TYPE__)-1) \ + for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++); \ + for (i = nptrs; i >= 1; i--) \ + __CTOR_LIST__[i] (); \ +} while (0) +#endif + +#endif /* GCC_GBL_CTORS_H */ diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c new file mode 100644 index 0000000..57c40c5 --- /dev/null +++ b/libgcc/libgcc2.c @@ -0,0 +1,2252 @@ +/* More subroutines needed by GCC output code on some machines. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "tconfig.h" +#include "tsystem.h" +#include "coretypes.h" +#include "tm.h" + +#ifdef HAVE_GAS_HIDDEN +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) +#else +#define ATTRIBUTE_HIDDEN +#endif + +/* Work out the largest "word" size that we can deal with on this target. */ +#if MIN_UNITS_PER_WORD > 4 +# define LIBGCC2_MAX_UNITS_PER_WORD 8 +#elif (MIN_UNITS_PER_WORD > 2 \ + || (MIN_UNITS_PER_WORD > 1 && __SIZEOF_LONG_LONG__ > 4)) +# define LIBGCC2_MAX_UNITS_PER_WORD 4 +#else +# define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD +#endif + +/* Work out what word size we are using for this compilation. + The value can be set on the command line. */ +#ifndef LIBGCC2_UNITS_PER_WORD +#define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD +#endif + +#if LIBGCC2_UNITS_PER_WORD <= LIBGCC2_MAX_UNITS_PER_WORD + +#include "libgcc2.h" + +#ifdef DECLARE_LIBRARY_RENAMES + DECLARE_LIBRARY_RENAMES +#endif + +#if defined (L_negdi2) +DWtype +__negdi2 (DWtype u) +{ + const DWunion uu = {.ll = u}; + const DWunion w = { {.low = -uu.s.low, + .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } }; + + return w.ll; +} +#endif + +#ifdef L_addvsi3 +Wtype +__addvSI3 (Wtype a, Wtype b) +{ + const Wtype w = (UWtype) a + (UWtype) b; + + if (b >= 0 ? w < a : w > a) + abort (); + + return w; +} +#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC +SItype +__addvsi3 (SItype a, SItype b) +{ + const SItype w = (USItype) a + (USItype) b; + + if (b >= 0 ? w < a : w > a) + abort (); + + return w; +} +#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ +#endif + +#ifdef L_addvdi3 +DWtype +__addvDI3 (DWtype a, DWtype b) +{ + const DWtype w = (UDWtype) a + (UDWtype) b; + + if (b >= 0 ? w < a : w > a) + abort (); + + return w; +} +#endif + +#ifdef L_subvsi3 +Wtype +__subvSI3 (Wtype a, Wtype b) +{ + const Wtype w = (UWtype) a - (UWtype) b; + + if (b >= 0 ? w > a : w < a) + abort (); + + return w; +} +#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC +SItype +__subvsi3 (SItype a, SItype b) +{ + const SItype w = (USItype) a - (USItype) b; + + if (b >= 0 ? w > a : w < a) + abort (); + + return w; +} +#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ +#endif + +#ifdef L_subvdi3 +DWtype +__subvDI3 (DWtype a, DWtype b) +{ + const DWtype w = (UDWtype) a - (UDWtype) b; + + if (b >= 0 ? w > a : w < a) + abort (); + + return w; +} +#endif + +#ifdef L_mulvsi3 +Wtype +__mulvSI3 (Wtype a, Wtype b) +{ + const DWtype w = (DWtype) a * (DWtype) b; + + if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1)) + abort (); + + return w; +} +#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC +#undef WORD_SIZE +#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) +SItype +__mulvsi3 (SItype a, SItype b) +{ + const DItype w = (DItype) a * (DItype) b; + + if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1)) + abort (); + + return w; +} +#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ +#endif + +#ifdef L_negvsi2 +Wtype +__negvSI2 (Wtype a) +{ + const Wtype w = -(UWtype) a; + + if (a >= 0 ? w > 0 : w < 0) + abort (); + + return w; +} +#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC +SItype +__negvsi2 (SItype a) +{ + const SItype w = -(USItype) a; + + if (a >= 0 ? w > 0 : w < 0) + abort (); + + return w; +} +#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ +#endif + +#ifdef L_negvdi2 +DWtype +__negvDI2 (DWtype a) +{ + const DWtype w = -(UDWtype) a; + + if (a >= 0 ? w > 0 : w < 0) + abort (); + + return w; +} +#endif + +#ifdef L_absvsi2 +Wtype +__absvSI2 (Wtype a) +{ + Wtype w = a; + + if (a < 0) +#ifdef L_negvsi2 + w = __negvSI2 (a); +#else + w = -(UWtype) a; + + if (w < 0) + abort (); +#endif + + return w; +} +#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC +SItype +__absvsi2 (SItype a) +{ + SItype w = a; + + if (a < 0) +#ifdef L_negvsi2 + w = __negvsi2 (a); +#else + w = -(USItype) a; + + if (w < 0) + abort (); +#endif + + return w; +} +#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ +#endif + +#ifdef L_absvdi2 +DWtype +__absvDI2 (DWtype a) +{ + DWtype w = a; + + if (a < 0) +#ifdef L_negvdi2 + w = __negvDI2 (a); +#else + w = -(UDWtype) a; + + if (w < 0) + abort (); +#endif + + return w; +} +#endif + +#ifdef L_mulvdi3 +DWtype +__mulvDI3 (DWtype u, DWtype v) +{ + /* The unchecked multiplication needs 3 Wtype x Wtype multiplications, + but the checked multiplication needs only two. */ + const DWunion uu = {.ll = u}; + const DWunion vv = {.ll = v}; + + if (__builtin_expect (uu.s.high == uu.s.low >> (W_TYPE_SIZE - 1), 1)) + { + /* u fits in a single Wtype. */ + if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1)) + { + /* v fits in a single Wtype as well. */ + /* A single multiplication. No overflow risk. */ + return (DWtype) uu.s.low * (DWtype) vv.s.low; + } + else + { + /* Two multiplications. */ + DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low + * (UDWtype) (UWtype) vv.s.low}; + DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low + * (UDWtype) (UWtype) vv.s.high}; + + if (vv.s.high < 0) + w1.s.high -= uu.s.low; + if (uu.s.low < 0) + w1.ll -= vv.ll; + w1.ll += (UWtype) w0.s.high; + if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1)) + { + w0.s.high = w1.s.low; + return w0.ll; + } + } + } + else + { + if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1)) + { + /* v fits into a single Wtype. */ + /* Two multiplications. */ + DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low + * (UDWtype) (UWtype) vv.s.low}; + DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high + * (UDWtype) (UWtype) vv.s.low}; + + if (uu.s.high < 0) + w1.s.high -= vv.s.low; + if (vv.s.low < 0) + w1.ll -= uu.ll; + w1.ll += (UWtype) w0.s.high; + if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1)) + { + w0.s.high = w1.s.low; + return w0.ll; + } + } + else + { + /* A few sign checks and a single multiplication. */ + if (uu.s.high >= 0) + { + if (vv.s.high >= 0) + { + if (uu.s.high == 0 && vv.s.high == 0) + { + const DWtype w = (UDWtype) (UWtype) uu.s.low + * (UDWtype) (UWtype) vv.s.low; + if (__builtin_expect (w >= 0, 1)) + return w; + } + } + else + { + if (uu.s.high == 0 && vv.s.high == (Wtype) -1) + { + DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low + * (UDWtype) (UWtype) vv.s.low}; + + ww.s.high -= uu.s.low; + if (__builtin_expect (ww.s.high < 0, 1)) + return ww.ll; + } + } + } + else + { + if (vv.s.high >= 0) + { + if (uu.s.high == (Wtype) -1 && vv.s.high == 0) + { + DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low + * (UDWtype) (UWtype) vv.s.low}; + + ww.s.high -= vv.s.low; + if (__builtin_expect (ww.s.high < 0, 1)) + return ww.ll; + } + } + else + { + if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1) + { + DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low + * (UDWtype) (UWtype) vv.s.low}; + + ww.s.high -= uu.s.low; + ww.s.high -= vv.s.low; + if (__builtin_expect (ww.s.high >= 0, 1)) + return ww.ll; + } + } + } + } + } + + /* Overflow. */ + abort (); +} +#endif + + +/* Unless shift functions are defined with full ANSI prototypes, + parameter b will be promoted to int if shift_count_type is smaller than an int. */ +#ifdef L_lshrdi3 +DWtype +__lshrdi3 (DWtype u, shift_count_type b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const shift_count_type bm = W_TYPE_SIZE - b; + DWunion w; + + if (bm <= 0) + { + w.s.high = 0; + w.s.low = (UWtype) uu.s.high >> -bm; + } + else + { + const UWtype carries = (UWtype) uu.s.high << bm; + + w.s.high = (UWtype) uu.s.high >> b; + w.s.low = ((UWtype) uu.s.low >> b) | carries; + } + + return w.ll; +} +#endif + +#ifdef L_ashldi3 +DWtype +__ashldi3 (DWtype u, shift_count_type b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const shift_count_type bm = W_TYPE_SIZE - b; + DWunion w; + + if (bm <= 0) + { + w.s.low = 0; + w.s.high = (UWtype) uu.s.low << -bm; + } + else + { + const UWtype carries = (UWtype) uu.s.low >> bm; + + w.s.low = (UWtype) uu.s.low << b; + w.s.high = ((UWtype) uu.s.high << b) | carries; + } + + return w.ll; +} +#endif + +#ifdef L_ashrdi3 +DWtype +__ashrdi3 (DWtype u, shift_count_type b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const shift_count_type bm = W_TYPE_SIZE - b; + DWunion w; + + if (bm <= 0) + { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (W_TYPE_SIZE - 1); + w.s.low = uu.s.high >> -bm; + } + else + { + const UWtype carries = (UWtype) uu.s.high << bm; + + w.s.high = uu.s.high >> b; + w.s.low = ((UWtype) uu.s.low >> b) | carries; + } + + return w.ll; +} +#endif + +#ifdef L_bswapsi2 +SItype +__bswapsi2 (SItype u) +{ + return ((((u) & 0xff000000) >> 24) + | (((u) & 0x00ff0000) >> 8) + | (((u) & 0x0000ff00) << 8) + | (((u) & 0x000000ff) << 24)); +} +#endif +#ifdef L_bswapdi2 +DItype +__bswapdi2 (DItype u) +{ + return ((((u) & 0xff00000000000000ull) >> 56) + | (((u) & 0x00ff000000000000ull) >> 40) + | (((u) & 0x0000ff0000000000ull) >> 24) + | (((u) & 0x000000ff00000000ull) >> 8) + | (((u) & 0x00000000ff000000ull) << 8) + | (((u) & 0x0000000000ff0000ull) << 24) + | (((u) & 0x000000000000ff00ull) << 40) + | (((u) & 0x00000000000000ffull) << 56)); +} +#endif +#ifdef L_ffssi2 +#undef int +int +__ffsSI2 (UWtype u) +{ + UWtype count; + + if (u == 0) + return 0; + + count_trailing_zeros (count, u); + return count + 1; +} +#endif + +#ifdef L_ffsdi2 +#undef int +int +__ffsDI2 (DWtype u) +{ + const DWunion uu = {.ll = u}; + UWtype word, count, add; + + if (uu.s.low != 0) + word = uu.s.low, add = 0; + else if (uu.s.high != 0) + word = uu.s.high, add = W_TYPE_SIZE; + else + return 0; + + count_trailing_zeros (count, word); + return count + add + 1; +} +#endif + +#ifdef L_muldi3 +DWtype +__muldi3 (DWtype u, DWtype v) +{ + const DWunion uu = {.ll = u}; + const DWunion vv = {.ll = v}; + DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)}; + + w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high + + (UWtype) uu.s.high * (UWtype) vv.s.low); + + return w.ll; +} +#endif + +#if (defined (L_udivdi3) || defined (L_divdi3) || \ + defined (L_umoddi3) || defined (L_moddi3)) +#if defined (sdiv_qrnnd) +#define L_udiv_w_sdiv +#endif +#endif + +#ifdef L_udiv_w_sdiv +#if defined (sdiv_qrnnd) +#if (defined (L_udivdi3) || defined (L_divdi3) || \ + defined (L_umoddi3) || defined (L_moddi3)) +static inline __attribute__ ((__always_inline__)) +#endif +UWtype +__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d) +{ + UWtype q, r; + UWtype c0, c1, b1; + + if ((Wtype) d >= 0) + { + if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1))) + { + /* Dividend, divisor, and quotient are nonnegative. */ + sdiv_qrnnd (q, r, a1, a0, d); + } + else + { + /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d. */ + sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1)); + /* Divide (c1*2^32 + c0) by d. */ + sdiv_qrnnd (q, r, c1, c0, d); + /* Add 2^31 to quotient. */ + q += (UWtype) 1 << (W_TYPE_SIZE - 1); + } + } + else + { + b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ + c1 = a1 >> 1; /* A/2 */ + c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1); + + if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ + { + sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ + + r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ + if ((d & 1) != 0) + { + if (r >= q) + r = r - q; + else if (q - r <= d) + { + r = r - q + d; + q--; + } + else + { + r = r - q + 2*d; + q -= 2; + } + } + } + else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ + { + c1 = (b1 - 1) - c1; + c0 = ~c0; /* logical NOT */ + + sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ + + q = ~q; /* (A/2)/b1 */ + r = (b1 - 1) - r; + + r = 2*r + (a0 & 1); /* A/(2*b1) */ + + if ((d & 1) != 0) + { + if (r >= q) + r = r - q; + else if (q - r <= d) + { + r = r - q + d; + q--; + } + else + { + r = r - q + 2*d; + q -= 2; + } + } + } + else /* Implies c1 = b1 */ + { /* Hence a1 = d - 1 = 2*b1 - 1 */ + if (a0 >= -d) + { + q = -1; + r = a0 + d; + } + else + { + q = -2; + r = a0 + 2*d; + } + } + } + + *rp = r; + return q; +} +#else +/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */ +UWtype +__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)), + UWtype a1 __attribute__ ((__unused__)), + UWtype a0 __attribute__ ((__unused__)), + UWtype d __attribute__ ((__unused__))) +{ + return 0; +} +#endif +#endif + +#if (defined (L_udivdi3) || defined (L_divdi3) || \ + defined (L_umoddi3) || defined (L_moddi3)) +#define L_udivmoddi4 +#endif + +#ifdef L_clz +const UQItype __clz_tab[256] = +{ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 +}; +#endif + +#ifdef L_clzsi2 +#undef int +int +__clzSI2 (UWtype x) +{ + Wtype ret; + + count_leading_zeros (ret, x); + + return ret; +} +#endif + +#ifdef L_clzdi2 +#undef int +int +__clzDI2 (UDWtype x) +{ + const DWunion uu = {.ll = x}; + UWtype word; + Wtype ret, add; + + if (uu.s.high) + word = uu.s.high, add = 0; + else + word = uu.s.low, add = W_TYPE_SIZE; + + count_leading_zeros (ret, word); + return ret + add; +} +#endif + +#ifdef L_ctzsi2 +#undef int +int +__ctzSI2 (UWtype x) +{ + Wtype ret; + + count_trailing_zeros (ret, x); + + return ret; +} +#endif + +#ifdef L_ctzdi2 +#undef int +int +__ctzDI2 (UDWtype x) +{ + const DWunion uu = {.ll = x}; + UWtype word; + Wtype ret, add; + + if (uu.s.low) + word = uu.s.low, add = 0; + else + word = uu.s.high, add = W_TYPE_SIZE; + + count_trailing_zeros (ret, word); + return ret + add; +} +#endif + +#ifdef L_clrsbsi2 +#undef int +int +__clrsbSI2 (Wtype x) +{ + Wtype ret; + + if (x < 0) + x = ~x; + if (x == 0) + return W_TYPE_SIZE - 1; + count_leading_zeros (ret, x); + return ret - 1; +} +#endif + +#ifdef L_clrsbdi2 +#undef int +int +__clrsbDI2 (DWtype x) +{ + const DWunion uu = {.ll = x}; + UWtype word; + Wtype ret, add; + + if (uu.s.high == 0) + word = uu.s.low, add = W_TYPE_SIZE; + else if (uu.s.high == -1) + word = ~uu.s.low, add = W_TYPE_SIZE; + else if (uu.s.high >= 0) + word = uu.s.high, add = 0; + else + word = ~uu.s.high, add = 0; + + if (word == 0) + ret = W_TYPE_SIZE; + else + count_leading_zeros (ret, word); + + return ret + add - 1; +} +#endif + +#ifdef L_popcount_tab +const UQItype __popcount_tab[256] = +{ + 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 +}; +#endif + +#ifdef L_popcountsi2 +#undef int +int +__popcountSI2 (UWtype x) +{ + int i, ret = 0; + + for (i = 0; i < W_TYPE_SIZE; i += 8) + ret += __popcount_tab[(x >> i) & 0xff]; + + return ret; +} +#endif + +#ifdef L_popcountdi2 +#undef int +int +__popcountDI2 (UDWtype x) +{ + int i, ret = 0; + + for (i = 0; i < 2*W_TYPE_SIZE; i += 8) + ret += __popcount_tab[(x >> i) & 0xff]; + + return ret; +} +#endif + +#ifdef L_paritysi2 +#undef int +int +__paritySI2 (UWtype x) +{ +#if W_TYPE_SIZE > 64 +# error "fill out the table" +#endif +#if W_TYPE_SIZE > 32 + x ^= x >> 32; +#endif +#if W_TYPE_SIZE > 16 + x ^= x >> 16; +#endif + x ^= x >> 8; + x ^= x >> 4; + x &= 0xf; + return (0x6996 >> x) & 1; +} +#endif + +#ifdef L_paritydi2 +#undef int +int +__parityDI2 (UDWtype x) +{ + const DWunion uu = {.ll = x}; + UWtype nx = uu.s.low ^ uu.s.high; + +#if W_TYPE_SIZE > 64 +# error "fill out the table" +#endif +#if W_TYPE_SIZE > 32 + nx ^= nx >> 32; +#endif +#if W_TYPE_SIZE > 16 + nx ^= nx >> 16; +#endif + nx ^= nx >> 8; + nx ^= nx >> 4; + nx &= 0xf; + return (0x6996 >> nx) & 1; +} +#endif + +#ifdef L_udivmoddi4 + +#if (defined (L_udivdi3) || defined (L_divdi3) || \ + defined (L_umoddi3) || defined (L_moddi3)) +static inline __attribute__ ((__always_inline__)) +#endif +UDWtype +__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) +{ + const DWunion nn = {.ll = n}; + const DWunion dd = {.ll = d}; + DWunion rr; + UWtype d0, d1, n0, n1, n2; + UWtype q0, q1; + UWtype b, bm; + + d0 = dd.s.low; + d1 = dd.s.high; + n0 = nn.s.low; + n1 = nn.s.high; + +#if !UDIV_NEEDS_NORMALIZATION + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + udiv_qrnnd (q1, n1, 0, n1, d0); + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0. */ + } + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = 0; + *rp = rr.ll; + } + } + +#else /* UDIV_NEEDS_NORMALIZATION */ + + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + count_leading_zeros (bm, d0); + + if (bm != 0) + { + /* Normalize, i.e. make the most significant bit of the + denominator set. */ + + d0 = d0 << bm; + n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); + n0 = n0 << bm; + } + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0 >> bm. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + count_leading_zeros (bm, d0); + + if (bm == 0) + { + /* From (n1 >= d0) /\ (the most significant bit of d0 is set), + conclude (the most significant bit of n1 is set) /\ (the + leading quotient digit q1 = 1). + + This special case is necessary, not an optimization. + (Shifts counts of W_TYPE_SIZE are undefined.) */ + + n1 -= d0; + q1 = 1; + } + else + { + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q1, n1, n2, n1, d0); + } + + /* n1 != d0... */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0 >> bm. */ + } + + if (rp != 0) + { + rr.s.low = n0 >> bm; + rr.s.high = 0; + *rp = rr.ll; + } + } +#endif /* UDIV_NEEDS_NORMALIZATION */ + + else + { + if (d1 > n1) + { + /* 00 = nn / DD */ + + q0 = 0; + q1 = 0; + + /* Remainder in n1n0. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + /* 0q = NN / dd */ + + count_leading_zeros (bm, d1); + if (bm == 0) + { + /* From (n1 >= d1) /\ (the most significant bit of d1 is set), + conclude (the most significant bit of n1 is set) /\ (the + quotient digit q0 = 0 or 1). + + This special case is necessary, not an optimization. */ + + /* The condition on the next line takes advantage of that + n1 >= d1 (true due to program flow). */ + if (n1 > d1 || n0 >= d0) + { + q0 = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + else + q0 = 0; + + q1 = 0; + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + UWtype m1, m0; + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d1 = (d1 << bm) | (d0 >> b); + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q0, n1, n2, n1, d1); + umul_ppmm (m1, m0, q0, d0); + + if (m1 > n1 || (m1 == n1 && m0 > n0)) + { + q0--; + sub_ddmmss (m1, m0, m1, m0, d1, d0); + } + + q1 = 0; + + /* Remainder in (n1n0 - m1m0) >> bm. */ + if (rp != 0) + { + sub_ddmmss (n1, n0, n1, n0, m1, m0); + rr.s.low = (n1 << b) | (n0 >> bm); + rr.s.high = n1 >> bm; + *rp = rr.ll; + } + } + } + } + + const DWunion ww = {{.low = q0, .high = q1}}; + return ww.ll; +} +#endif + +#ifdef L_divdi3 +DWtype +__divdi3 (DWtype u, DWtype v) +{ + Wtype c = 0; + DWunion uu = {.ll = u}; + DWunion vv = {.ll = v}; + DWtype w; + + if (uu.s.high < 0) + c = ~c, + uu.ll = -uu.ll; + if (vv.s.high < 0) + c = ~c, + vv.ll = -vv.ll; + + w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0); + if (c) + w = -w; + + return w; +} +#endif + +#ifdef L_moddi3 +DWtype +__moddi3 (DWtype u, DWtype v) +{ + Wtype c = 0; + DWunion uu = {.ll = u}; + DWunion vv = {.ll = v}; + DWtype w; + + if (uu.s.high < 0) + c = ~c, + uu.ll = -uu.ll; + if (vv.s.high < 0) + vv.ll = -vv.ll; + + (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w); + if (c) + w = -w; + + return w; +} +#endif + +#ifdef L_umoddi3 +UDWtype +__umoddi3 (UDWtype u, UDWtype v) +{ + UDWtype w; + + (void) __udivmoddi4 (u, v, &w); + + return w; +} +#endif + +#ifdef L_udivdi3 +UDWtype +__udivdi3 (UDWtype n, UDWtype d) +{ + return __udivmoddi4 (n, d, (UDWtype *) 0); +} +#endif + +#ifdef L_cmpdi2 +cmp_return_type +__cmpdi2 (DWtype a, DWtype b) +{ + const DWunion au = {.ll = a}; + const DWunion bu = {.ll = b}; + + if (au.s.high < bu.s.high) + return 0; + else if (au.s.high > bu.s.high) + return 2; + if ((UWtype) au.s.low < (UWtype) bu.s.low) + return 0; + else if ((UWtype) au.s.low > (UWtype) bu.s.low) + return 2; + return 1; +} +#endif + +#ifdef L_ucmpdi2 +cmp_return_type +__ucmpdi2 (DWtype a, DWtype b) +{ + const DWunion au = {.ll = a}; + const DWunion bu = {.ll = b}; + + if ((UWtype) au.s.high < (UWtype) bu.s.high) + return 0; + else if ((UWtype) au.s.high > (UWtype) bu.s.high) + return 2; + if ((UWtype) au.s.low < (UWtype) bu.s.low) + return 0; + else if ((UWtype) au.s.low > (UWtype) bu.s.low) + return 2; + return 1; +} +#endif + +#if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE +UDWtype +__fixunstfDI (TFtype a) +{ + if (a < 0) + return 0; + + /* Compute high word of result, as a flonum. */ + const TFtype b = (a / Wtype_MAXp1_F); + /* Convert that to fixed (but not to DWtype!), + and shift it into the high word. */ + UDWtype v = (UWtype) b; + v <<= W_TYPE_SIZE; + /* Remove high part from the TFtype, leaving the low part as flonum. */ + a -= (TFtype)v; + /* Convert that to fixed (but not to DWtype!) and add it in. + Sometimes A comes out negative. This is significant, since + A has more bits than a long int does. */ + if (a < 0) + v -= (UWtype) (- a); + else + v += (UWtype) a; + return v; +} +#endif + +#if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE +DWtype +__fixtfdi (TFtype a) +{ + if (a < 0) + return - __fixunstfDI (-a); + return __fixunstfDI (a); +} +#endif + +#if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE +UDWtype +__fixunsxfDI (XFtype a) +{ + if (a < 0) + return 0; + + /* Compute high word of result, as a flonum. */ + const XFtype b = (a / Wtype_MAXp1_F); + /* Convert that to fixed (but not to DWtype!), + and shift it into the high word. */ + UDWtype v = (UWtype) b; + v <<= W_TYPE_SIZE; + /* Remove high part from the XFtype, leaving the low part as flonum. */ + a -= (XFtype)v; + /* Convert that to fixed (but not to DWtype!) and add it in. + Sometimes A comes out negative. This is significant, since + A has more bits than a long int does. */ + if (a < 0) + v -= (UWtype) (- a); + else + v += (UWtype) a; + return v; +} +#endif + +#if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE +DWtype +__fixxfdi (XFtype a) +{ + if (a < 0) + return - __fixunsxfDI (-a); + return __fixunsxfDI (a); +} +#endif + +#if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE +UDWtype +__fixunsdfDI (DFtype a) +{ + /* Get high part of result. The division here will just moves the radix + point and will not cause any rounding. Then the conversion to integral + type chops result as desired. */ + const UWtype hi = a / Wtype_MAXp1_F; + + /* Get low part of result. Convert `hi' to floating type and scale it back, + then subtract this from the number being converted. This leaves the low + part. Convert that to integral type. */ + const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F; + + /* Assemble result from the two parts. */ + return ((UDWtype) hi << W_TYPE_SIZE) | lo; +} +#endif + +#if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE +DWtype +__fixdfdi (DFtype a) +{ + if (a < 0) + return - __fixunsdfDI (-a); + return __fixunsdfDI (a); +} +#endif + +#if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE +UDWtype +__fixunssfDI (SFtype a) +{ +#if LIBGCC2_HAS_DF_MODE + /* Convert the SFtype to a DFtype, because that is surely not going + to lose any bits. Some day someone else can write a faster version + that avoids converting to DFtype, and verify it really works right. */ + const DFtype dfa = a; + + /* Get high part of result. The division here will just moves the radix + point and will not cause any rounding. Then the conversion to integral + type chops result as desired. */ + const UWtype hi = dfa / Wtype_MAXp1_F; + + /* Get low part of result. Convert `hi' to floating type and scale it back, + then subtract this from the number being converted. This leaves the low + part. Convert that to integral type. */ + const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F; + + /* Assemble result from the two parts. */ + return ((UDWtype) hi << W_TYPE_SIZE) | lo; +#elif FLT_MANT_DIG < W_TYPE_SIZE + if (a < 1) + return 0; + if (a < Wtype_MAXp1_F) + return (UWtype)a; + if (a < Wtype_MAXp1_F * Wtype_MAXp1_F) + { + /* Since we know that there are fewer significant bits in the SFmode + quantity than in a word, we know that we can convert out all the + significant bits in one step, and thus avoid losing bits. */ + + /* ??? This following loop essentially performs frexpf. If we could + use the real libm function, or poke at the actual bits of the fp + format, it would be significantly faster. */ + + UWtype shift = 0, counter; + SFtype msb; + + a /= Wtype_MAXp1_F; + for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1) + { + SFtype counterf = (UWtype)1 << counter; + if (a >= counterf) + { + shift |= counter; + a /= counterf; + } + } + + /* Rescale into the range of one word, extract the bits of that + one word, and shift the result into position. */ + a *= Wtype_MAXp1_F; + counter = a; + return (DWtype)counter << shift; + } + return -1; +#else +# error +#endif +} +#endif + +#if defined(L_fixsfdi) && LIBGCC2_HAS_SF_MODE +DWtype +__fixsfdi (SFtype a) +{ + if (a < 0) + return - __fixunssfDI (-a); + return __fixunssfDI (a); +} +#endif + +#if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE +XFtype +__floatdixf (DWtype u) +{ +#if W_TYPE_SIZE > XF_SIZE +# error +#endif + XFtype d = (Wtype) (u >> W_TYPE_SIZE); + d *= Wtype_MAXp1_F; + d += (UWtype)u; + return d; +} +#endif + +#if defined(L_floatundixf) && LIBGCC2_HAS_XF_MODE +XFtype +__floatundixf (UDWtype u) +{ +#if W_TYPE_SIZE > XF_SIZE +# error +#endif + XFtype d = (UWtype) (u >> W_TYPE_SIZE); + d *= Wtype_MAXp1_F; + d += (UWtype)u; + return d; +} +#endif + +#if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE +TFtype +__floatditf (DWtype u) +{ +#if W_TYPE_SIZE > TF_SIZE +# error +#endif + TFtype d = (Wtype) (u >> W_TYPE_SIZE); + d *= Wtype_MAXp1_F; + d += (UWtype)u; + return d; +} +#endif + +#if defined(L_floatunditf) && LIBGCC2_HAS_TF_MODE +TFtype +__floatunditf (UDWtype u) +{ +#if W_TYPE_SIZE > TF_SIZE +# error +#endif + TFtype d = (UWtype) (u >> W_TYPE_SIZE); + d *= Wtype_MAXp1_F; + d += (UWtype)u; + return d; +} +#endif + +#if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE) \ + || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE) +#define DI_SIZE (W_TYPE_SIZE * 2) +#define F_MODE_OK(SIZE) \ + (SIZE < DI_SIZE \ + && SIZE > (DI_SIZE - SIZE + FSSIZE) \ + && !AVOID_FP_TYPE_CONVERSION(SIZE)) +#if defined(L_floatdisf) +#define FUNC __floatdisf +#define FSTYPE SFtype +#define FSSIZE SF_SIZE +#else +#define FUNC __floatdidf +#define FSTYPE DFtype +#define FSSIZE DF_SIZE +#endif + +FSTYPE +FUNC (DWtype u) +{ +#if FSSIZE >= W_TYPE_SIZE + /* When the word size is small, we never get any rounding error. */ + FSTYPE f = (Wtype) (u >> W_TYPE_SIZE); + f *= Wtype_MAXp1_F; + f += (UWtype)u; + return f; +#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \ + || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \ + || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) + +#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) +# define FSIZE DF_SIZE +# define FTYPE DFtype +#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) +# define FSIZE XF_SIZE +# define FTYPE XFtype +#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) +# define FSIZE TF_SIZE +# define FTYPE TFtype +#else +# error +#endif + +#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE)) + + /* Protect against double-rounding error. + Represent any low-order bits, that might be truncated by a bit that + won't be lost. The bit can go in anywhere below the rounding position + of the FSTYPE. A fixed mask and bit position handles all usual + configurations. */ + if (! (- ((DWtype) 1 << FSIZE) < u + && u < ((DWtype) 1 << FSIZE))) + { + if ((UDWtype) u & (REP_BIT - 1)) + { + u &= ~ (REP_BIT - 1); + u |= REP_BIT; + } + } + + /* Do the calculation in a wider type so that we don't lose any of + the precision of the high word while multiplying it. */ + FTYPE f = (Wtype) (u >> W_TYPE_SIZE); + f *= Wtype_MAXp1_F; + f += (UWtype)u; + return (FSTYPE) f; +#else +#if FSSIZE >= W_TYPE_SIZE - 2 +# error +#endif + /* Finally, the word size is larger than the number of bits in the + required FSTYPE, and we've got no suitable wider type. The only + way to avoid double rounding is to special case the + extraction. */ + + /* If there are no high bits set, fall back to one conversion. */ + if ((Wtype)u == u) + return (FSTYPE)(Wtype)u; + + /* Otherwise, find the power of two. */ + Wtype hi = u >> W_TYPE_SIZE; + if (hi < 0) + hi = -hi; + + UWtype count, shift; + count_leading_zeros (count, hi); + + /* No leading bits means u == minimum. */ + if (count == 0) + return -(Wtype_MAXp1_F * (Wtype_MAXp1_F / 2)); + + shift = 1 + W_TYPE_SIZE - count; + + /* Shift down the most significant bits. */ + hi = u >> shift; + + /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ + if ((UWtype)u << (W_TYPE_SIZE - shift)) + hi |= 1; + + /* Convert the one word of data, and rescale. */ + FSTYPE f = hi, e; + if (shift == W_TYPE_SIZE) + e = Wtype_MAXp1_F; + /* The following two cases could be merged if we knew that the target + supported a native unsigned->float conversion. More often, we only + have a signed conversion, and have to add extra fixup code. */ + else if (shift == W_TYPE_SIZE - 1) + e = Wtype_MAXp1_F / 2; + else + e = (Wtype)1 << shift; + return f * e; +#endif +} +#endif + +#if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE) \ + || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE) +#define DI_SIZE (W_TYPE_SIZE * 2) +#define F_MODE_OK(SIZE) \ + (SIZE < DI_SIZE \ + && SIZE > (DI_SIZE - SIZE + FSSIZE) \ + && !AVOID_FP_TYPE_CONVERSION(SIZE)) +#if defined(L_floatundisf) +#define FUNC __floatundisf +#define FSTYPE SFtype +#define FSSIZE SF_SIZE +#else +#define FUNC __floatundidf +#define FSTYPE DFtype +#define FSSIZE DF_SIZE +#endif + +FSTYPE +FUNC (UDWtype u) +{ +#if FSSIZE >= W_TYPE_SIZE + /* When the word size is small, we never get any rounding error. */ + FSTYPE f = (UWtype) (u >> W_TYPE_SIZE); + f *= Wtype_MAXp1_F; + f += (UWtype)u; + return f; +#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \ + || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \ + || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) + +#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) +# define FSIZE DF_SIZE +# define FTYPE DFtype +#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) +# define FSIZE XF_SIZE +# define FTYPE XFtype +#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) +# define FSIZE TF_SIZE +# define FTYPE TFtype +#else +# error +#endif + +#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE)) + + /* Protect against double-rounding error. + Represent any low-order bits, that might be truncated by a bit that + won't be lost. The bit can go in anywhere below the rounding position + of the FSTYPE. A fixed mask and bit position handles all usual + configurations. */ + if (u >= ((UDWtype) 1 << FSIZE)) + { + if ((UDWtype) u & (REP_BIT - 1)) + { + u &= ~ (REP_BIT - 1); + u |= REP_BIT; + } + } + + /* Do the calculation in a wider type so that we don't lose any of + the precision of the high word while multiplying it. */ + FTYPE f = (UWtype) (u >> W_TYPE_SIZE); + f *= Wtype_MAXp1_F; + f += (UWtype)u; + return (FSTYPE) f; +#else +#if FSSIZE == W_TYPE_SIZE - 1 +# error +#endif + /* Finally, the word size is larger than the number of bits in the + required FSTYPE, and we've got no suitable wider type. The only + way to avoid double rounding is to special case the + extraction. */ + + /* If there are no high bits set, fall back to one conversion. */ + if ((UWtype)u == u) + return (FSTYPE)(UWtype)u; + + /* Otherwise, find the power of two. */ + UWtype hi = u >> W_TYPE_SIZE; + + UWtype count, shift; + count_leading_zeros (count, hi); + + shift = W_TYPE_SIZE - count; + + /* Shift down the most significant bits. */ + hi = u >> shift; + + /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ + if ((UWtype)u << (W_TYPE_SIZE - shift)) + hi |= 1; + + /* Convert the one word of data, and rescale. */ + FSTYPE f = hi, e; + if (shift == W_TYPE_SIZE) + e = Wtype_MAXp1_F; + /* The following two cases could be merged if we knew that the target + supported a native unsigned->float conversion. More often, we only + have a signed conversion, and have to add extra fixup code. */ + else if (shift == W_TYPE_SIZE - 1) + e = Wtype_MAXp1_F / 2; + else + e = (Wtype)1 << shift; + return f * e; +#endif +} +#endif + +#if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE +/* Reenable the normal types, in case limits.h needs them. */ +#undef char +#undef short +#undef int +#undef long +#undef unsigned +#undef float +#undef double +#undef MIN +#undef MAX +#include <limits.h> + +UWtype +__fixunsxfSI (XFtype a) +{ + if (a >= - (DFtype) Wtype_MIN) + return (Wtype) (a + Wtype_MIN) - Wtype_MIN; + return (Wtype) a; +} +#endif + +#if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE +/* Reenable the normal types, in case limits.h needs them. */ +#undef char +#undef short +#undef int +#undef long +#undef unsigned +#undef float +#undef double +#undef MIN +#undef MAX +#include <limits.h> + +UWtype +__fixunsdfSI (DFtype a) +{ + if (a >= - (DFtype) Wtype_MIN) + return (Wtype) (a + Wtype_MIN) - Wtype_MIN; + return (Wtype) a; +} +#endif + +#if defined(L_fixunssfsi) && LIBGCC2_HAS_SF_MODE +/* Reenable the normal types, in case limits.h needs them. */ +#undef char +#undef short +#undef int +#undef long +#undef unsigned +#undef float +#undef double +#undef MIN +#undef MAX +#include <limits.h> + +UWtype +__fixunssfSI (SFtype a) +{ + if (a >= - (SFtype) Wtype_MIN) + return (Wtype) (a + Wtype_MIN) - Wtype_MIN; + return (Wtype) a; +} +#endif + +/* Integer power helper used from __builtin_powi for non-constant + exponents. */ + +#if (defined(L_powisf2) && LIBGCC2_HAS_SF_MODE) \ + || (defined(L_powidf2) && LIBGCC2_HAS_DF_MODE) \ + || (defined(L_powixf2) && LIBGCC2_HAS_XF_MODE) \ + || (defined(L_powitf2) && LIBGCC2_HAS_TF_MODE) +# if defined(L_powisf2) +# define TYPE SFtype +# define NAME __powisf2 +# elif defined(L_powidf2) +# define TYPE DFtype +# define NAME __powidf2 +# elif defined(L_powixf2) +# define TYPE XFtype +# define NAME __powixf2 +# elif defined(L_powitf2) +# define TYPE TFtype +# define NAME __powitf2 +# endif + +#undef int +#undef unsigned +TYPE +NAME (TYPE x, int m) +{ + unsigned int n = m < 0 ? -m : m; + TYPE y = n % 2 ? x : 1; + while (n >>= 1) + { + x = x * x; + if (n % 2) + y = y * x; + } + return m < 0 ? 1/y : y; +} + +#endif + +#if ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \ + || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \ + || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \ + || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE) + +#undef float +#undef double +#undef long + +#if defined(L_mulsc3) || defined(L_divsc3) +# define MTYPE SFtype +# define CTYPE SCtype +# define MODE sc +# define CEXT f +# define NOTRUNC __FLT_EVAL_METHOD__ == 0 +#elif defined(L_muldc3) || defined(L_divdc3) +# define MTYPE DFtype +# define CTYPE DCtype +# define MODE dc +# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64 +# define CEXT l +# define NOTRUNC 1 +# else +# define CEXT +# define NOTRUNC __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1 +# endif +#elif defined(L_mulxc3) || defined(L_divxc3) +# define MTYPE XFtype +# define CTYPE XCtype +# define MODE xc +# define CEXT l +# define NOTRUNC 1 +#elif defined(L_multc3) || defined(L_divtc3) +# define MTYPE TFtype +# define CTYPE TCtype +# define MODE tc +# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128 +# define CEXT l +# else +# define CEXT LIBGCC2_TF_CEXT +# endif +# define NOTRUNC 1 +#else +# error +#endif + +#define CONCAT3(A,B,C) _CONCAT3(A,B,C) +#define _CONCAT3(A,B,C) A##B##C + +#define CONCAT2(A,B) _CONCAT2(A,B) +#define _CONCAT2(A,B) A##B + +/* All of these would be present in a full C99 implementation of <math.h> + and <complex.h>. Our problem is that only a few systems have such full + implementations. Further, libgcc_s.so isn't currently linked against + libm.so, and even for systems that do provide full C99, the extra overhead + of all programs using libgcc having to link against libm. So avoid it. */ + +#define isnan(x) __builtin_expect ((x) != (x), 0) +#define isfinite(x) __builtin_expect (!isnan((x) - (x)), 1) +#define isinf(x) __builtin_expect (!isnan(x) & !isfinite(x), 0) + +#define INFINITY CONCAT2(__builtin_huge_val, CEXT) () +#define I 1i + +/* Helpers to make the following code slightly less gross. */ +#define COPYSIGN CONCAT2(__builtin_copysign, CEXT) +#define FABS CONCAT2(__builtin_fabs, CEXT) + +/* Verify that MTYPE matches up with CEXT. */ +extern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1]; + +/* Ensure that we've lost any extra precision. */ +#if NOTRUNC +# define TRUNC(x) +#else +# define TRUNC(x) __asm__ ("" : "=m"(x) : "m"(x)) +#endif + +#if defined(L_mulsc3) || defined(L_muldc3) \ + || defined(L_mulxc3) || defined(L_multc3) + +CTYPE +CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) +{ + MTYPE ac, bd, ad, bc, x, y; + CTYPE res; + + ac = a * c; + bd = b * d; + ad = a * d; + bc = b * c; + + TRUNC (ac); + TRUNC (bd); + TRUNC (ad); + TRUNC (bc); + + x = ac - bd; + y = ad + bc; + + if (isnan (x) && isnan (y)) + { + /* Recover infinities that computed as NaN + iNaN. */ + _Bool recalc = 0; + if (isinf (a) || isinf (b)) + { + /* z is infinite. "Box" the infinity and change NaNs in + the other factor to 0. */ + a = COPYSIGN (isinf (a) ? 1 : 0, a); + b = COPYSIGN (isinf (b) ? 1 : 0, b); + if (isnan (c)) c = COPYSIGN (0, c); + if (isnan (d)) d = COPYSIGN (0, d); + recalc = 1; + } + if (isinf (c) || isinf (d)) + { + /* w is infinite. "Box" the infinity and change NaNs in + the other factor to 0. */ + c = COPYSIGN (isinf (c) ? 1 : 0, c); + d = COPYSIGN (isinf (d) ? 1 : 0, d); + if (isnan (a)) a = COPYSIGN (0, a); + if (isnan (b)) b = COPYSIGN (0, b); + recalc = 1; + } + if (!recalc + && (isinf (ac) || isinf (bd) + || isinf (ad) || isinf (bc))) + { + /* Recover infinities from overflow by changing NaNs to 0. */ + if (isnan (a)) a = COPYSIGN (0, a); + if (isnan (b)) b = COPYSIGN (0, b); + if (isnan (c)) c = COPYSIGN (0, c); + if (isnan (d)) d = COPYSIGN (0, d); + recalc = 1; + } + if (recalc) + { + x = INFINITY * (a * c - b * d); + y = INFINITY * (a * d + b * c); + } + } + + __real__ res = x; + __imag__ res = y; + return res; +} +#endif /* complex multiply */ + +#if defined(L_divsc3) || defined(L_divdc3) \ + || defined(L_divxc3) || defined(L_divtc3) + +CTYPE +CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) +{ + MTYPE denom, ratio, x, y; + CTYPE res; + + /* ??? We can get better behavior from logarithmic scaling instead of + the division. But that would mean starting to link libgcc against + libm. We could implement something akin to ldexp/frexp as gcc builtins + fairly easily... */ + if (FABS (c) < FABS (d)) + { + ratio = c / d; + denom = (c * ratio) + d; + x = ((a * ratio) + b) / denom; + y = ((b * ratio) - a) / denom; + } + else + { + ratio = d / c; + denom = (d * ratio) + c; + x = ((b * ratio) + a) / denom; + y = (b - (a * ratio)) / denom; + } + + /* Recover infinities and zeros that computed as NaN+iNaN; the only cases + are nonzero/zero, infinite/finite, and finite/infinite. */ + if (isnan (x) && isnan (y)) + { + if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b))) + { + x = COPYSIGN (INFINITY, c) * a; + y = COPYSIGN (INFINITY, c) * b; + } + else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d)) + { + a = COPYSIGN (isinf (a) ? 1 : 0, a); + b = COPYSIGN (isinf (b) ? 1 : 0, b); + x = INFINITY * (a * c + b * d); + y = INFINITY * (b * c - a * d); + } + else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b)) + { + c = COPYSIGN (isinf (c) ? 1 : 0, c); + d = COPYSIGN (isinf (d) ? 1 : 0, d); + x = 0.0 * (a * c + b * d); + y = 0.0 * (b * c - a * d); + } + } + + __real__ res = x; + __imag__ res = y; + return res; +} +#endif /* complex divide */ + +#endif /* all complex float routines */ + +/* From here on down, the routines use normal data types. */ + +#define SItype bogus_type +#define USItype bogus_type +#define DItype bogus_type +#define UDItype bogus_type +#define SFtype bogus_type +#define DFtype bogus_type +#undef Wtype +#undef UWtype +#undef HWtype +#undef UHWtype +#undef DWtype +#undef UDWtype + +#undef char +#undef short +#undef int +#undef long +#undef unsigned +#undef float +#undef double + +#ifdef L__gcc_bcmp + +/* Like bcmp except the sign is meaningful. + Result is negative if S1 is less than S2, + positive if S1 is greater, 0 if S1 and S2 are equal. */ + +int +__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size) +{ + while (size > 0) + { + const unsigned char c1 = *s1++, c2 = *s2++; + if (c1 != c2) + return c1 - c2; + size--; + } + return 0; +} + +#endif + +/* __eprintf used to be used by GCC's private version of <assert.h>. + We no longer provide that header, but this routine remains in libgcc.a + for binary backward compatibility. Note that it is not included in + the shared version of libgcc. */ +#ifdef L_eprintf +#ifndef inhibit_libc + +#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ +#include <stdio.h> + +void +__eprintf (const char *string, const char *expression, + unsigned int line, const char *filename) +{ + fprintf (stderr, string, expression, line, filename); + fflush (stderr); + abort (); +} + +#endif +#endif + + +#ifdef L_clear_cache +/* Clear part of an instruction cache. */ + +void +__clear_cache (char *beg __attribute__((__unused__)), + char *end __attribute__((__unused__))) +{ +#ifdef CLEAR_INSN_CACHE + CLEAR_INSN_CACHE (beg, end); +#endif /* CLEAR_INSN_CACHE */ +} + +#endif /* L_clear_cache */ + +#ifdef L_trampoline + +/* Jump to a trampoline, loading the static chain address. */ + +#if defined(WINNT) && ! defined(__CYGWIN__) +#include <windows.h> +int getpagesize (void); +int mprotect (char *,int, int); + +int +getpagesize (void) +{ +#ifdef _ALPHA_ + return 8192; +#else + return 4096; +#endif +} + +int +mprotect (char *addr, int len, int prot) +{ + DWORD np, op; + + if (prot == 7) + np = 0x40; + else if (prot == 5) + np = 0x20; + else if (prot == 4) + np = 0x10; + else if (prot == 3) + np = 0x04; + else if (prot == 1) + np = 0x02; + else if (prot == 0) + np = 0x01; + else + return -1; + + if (VirtualProtect (addr, len, np, &op)) + return 0; + else + return -1; +} + +#endif /* WINNT && ! __CYGWIN__ */ + +#ifdef TRANSFER_FROM_TRAMPOLINE +TRANSFER_FROM_TRAMPOLINE +#endif +#endif /* L_trampoline */ + +#ifndef __CYGWIN__ +#ifdef L__main + +#include "gbl-ctors.h" + +/* Some systems use __main in a way incompatible with its use in gcc, in these + cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to + give the same symbol without quotes for an alternative entry point. You + must define both, or neither. */ +#ifndef NAME__MAIN +#define NAME__MAIN "__main" +#define SYMBOL__MAIN __main +#endif + +#if defined (INIT_SECTION_ASM_OP) || defined (INIT_ARRAY_SECTION_ASM_OP) +#undef HAS_INIT_SECTION +#define HAS_INIT_SECTION +#endif + +#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF) + +/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this + code to run constructors. In that case, we need to handle EH here, too. */ + +#ifdef EH_FRAME_SECTION_NAME +#include "unwind-dw2-fde.h" +extern unsigned char __EH_FRAME_BEGIN__[]; +#endif + +/* Run all the global destructors on exit from the program. */ + +void +__do_global_dtors (void) +{ +#ifdef DO_GLOBAL_DTORS_BODY + DO_GLOBAL_DTORS_BODY; +#else + static func_ptr *p = __DTOR_LIST__ + 1; + while (*p) + { + p++; + (*(p-1)) (); + } +#endif +#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) + { + static int completed = 0; + if (! completed) + { + completed = 1; + __deregister_frame_info (__EH_FRAME_BEGIN__); + } + } +#endif +} +#endif + +#ifndef HAS_INIT_SECTION +/* Run all the global constructors on entry to the program. */ + +void +__do_global_ctors (void) +{ +#ifdef EH_FRAME_SECTION_NAME + { + static struct object object; + __register_frame_info (__EH_FRAME_BEGIN__, &object); + } +#endif + DO_GLOBAL_CTORS_BODY; + atexit (__do_global_dtors); +} +#endif /* no HAS_INIT_SECTION */ + +#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main) +/* Subroutine called automatically by `main'. + Compiling a global function named `main' + produces an automatic call to this function at the beginning. + + For many systems, this routine calls __do_global_ctors. + For systems which support a .init section we use the .init section + to run __do_global_ctors, so we need not do anything here. */ + +extern void SYMBOL__MAIN (void); +void +SYMBOL__MAIN (void) +{ + /* Support recursive calls to `main': run initializers just once. */ + static int initialized; + if (! initialized) + { + initialized = 1; + __do_global_ctors (); + } +} +#endif /* no HAS_INIT_SECTION or INVOKE__main */ + +#endif /* L__main */ +#endif /* __CYGWIN__ */ + +#ifdef L_ctors + +#include "gbl-ctors.h" + +/* Provide default definitions for the lists of constructors and + destructors, so that we don't get linker errors. These symbols are + intentionally bss symbols, so that gld and/or collect will provide + the right values. */ + +/* We declare the lists here with two elements each, + so that they are valid empty lists if no other definition is loaded. + + If we are using the old "set" extensions to have the gnu linker + collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__ + must be in the bss/common section. + + Long term no port should use those extensions. But many still do. */ +#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY) +#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2) +func_ptr __CTOR_LIST__[2] = {0, 0}; +func_ptr __DTOR_LIST__[2] = {0, 0}; +#else +func_ptr __CTOR_LIST__[2]; +func_ptr __DTOR_LIST__[2]; +#endif +#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ +#endif /* L_ctors */ +#endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */ diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h new file mode 100644 index 0000000..0c7d0e1 --- /dev/null +++ b/libgcc/libgcc2.h @@ -0,0 +1,530 @@ +/* Header file for libgcc2.c. */ +/* Copyright (C) 2000, 2001, 2004, 2005, 2009, 2010 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_LIBGCC2_H +#define GCC_LIBGCC2_H + +#ifndef HIDE_EXPORTS +#pragma GCC visibility push(default) +#endif + +extern int __gcc_bcmp (const unsigned char *, const unsigned char *, size_t); +extern void __clear_cache (char *, char *); +extern void __eprintf (const char *, const char *, unsigned int, const char *) + __attribute__ ((__noreturn__)); + +#ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE +#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE +#endif + +#ifndef LIBGCC2_HAS_SF_MODE +#define LIBGCC2_HAS_SF_MODE (BITS_PER_UNIT == 8) +#endif + +#ifndef LIBGCC2_HAS_DF_MODE +#define LIBGCC2_HAS_DF_MODE \ + (BITS_PER_UNIT == 8 \ + && (__SIZEOF_DOUBLE__ * __CHAR_BIT__ == 64 \ + || LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64)) +#endif + +#ifndef LIBGCC2_HAS_XF_MODE +#define LIBGCC2_HAS_XF_MODE \ + (BITS_PER_UNIT == 8 && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80) +#endif + +#ifndef LIBGCC2_HAS_TF_MODE +#define LIBGCC2_HAS_TF_MODE \ + (BITS_PER_UNIT == 8 && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) +#endif + +#ifndef SF_SIZE +#if LIBGCC2_HAS_SF_MODE +#define SF_SIZE FLT_MANT_DIG +#else +#define SF_SIZE 0 +#endif +#endif + +#ifndef DF_SIZE +#if LIBGCC2_HAS_DF_MODE +#if __SIZEOF_DOUBLE__ * __CHAR_BIT__ == 64 +#define DF_SIZE DBL_MANT_DIG +#elif LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64 +#define DF_SIZE LDBL_MANT_DIG +#else +#define DF_SIZE 0 +#endif +#else +#define DF_SIZE 0 +#endif +#endif + +#ifndef XF_SIZE +#if LIBGCC2_HAS_XF_MODE +#define XF_SIZE LDBL_MANT_DIG +#else +#define XF_SIZE 0 +#endif +#endif + +#ifndef TF_SIZE +#if LIBGCC2_HAS_TF_MODE +#define TF_SIZE LDBL_MANT_DIG +#else +#define TF_SIZE 0 +#endif +#endif + +/* FIXME: This #ifdef probably should be removed, ie. enable the test + for mips too. */ +/* Don't use IBM Extended Double TFmode for TI->SF calculations. + The conversion from long double to float suffers from double + rounding, because we convert via double. In other cases, going + through the software fp routines is much slower than the fallback. */ +#ifdef __powerpc__ +#define AVOID_FP_TYPE_CONVERSION(SIZE) (SIZE == 106) +#elif defined(WIDEST_HARDWARE_FP_SIZE) +#define AVOID_FP_TYPE_CONVERSION(SIZE) (SIZE > WIDEST_HARDWARE_FP_SIZE) +#else +#define AVOID_FP_TYPE_CONVERSION(SIZE) 0 +#endif + +/* In the first part of this file, we are interfacing to calls generated + by the compiler itself. These calls pass values into these routines + which have very specific modes (rather than very specific types), and + these compiler-generated calls also expect any return values to have + very specific modes (rather than very specific types). Thus, we need + to avoid using regular C language type names in this part of the file + because the sizes for those types can be configured to be anything. + Instead we use the following special type names. */ + +typedef int QItype __attribute__ ((mode (QI))); +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +#if MIN_UNITS_PER_WORD > 1 +/* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1. */ +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +#if __SIZEOF_LONG_LONG__ > 4 +/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2. */ +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +#if MIN_UNITS_PER_WORD > 4 +/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 4. */ +typedef int TItype __attribute__ ((mode (TI))); +typedef unsigned int UTItype __attribute__ ((mode (TI))); +#endif +#endif +#endif + +#if LIBGCC2_HAS_SF_MODE +typedef float SFtype __attribute__ ((mode (SF))); +typedef _Complex float SCtype __attribute__ ((mode (SC))); +#endif +#if LIBGCC2_HAS_DF_MODE +typedef float DFtype __attribute__ ((mode (DF))); +typedef _Complex float DCtype __attribute__ ((mode (DC))); +#endif +#if LIBGCC2_HAS_XF_MODE +typedef float XFtype __attribute__ ((mode (XF))); +typedef _Complex float XCtype __attribute__ ((mode (XC))); +#endif +#if LIBGCC2_HAS_TF_MODE +typedef float TFtype __attribute__ ((mode (TF))); +typedef _Complex float TCtype __attribute__ ((mode (TC))); +#endif + +typedef int cmp_return_type __attribute__((mode (__libgcc_cmp_return__))); +typedef int shift_count_type __attribute__((mode (__libgcc_shift_count__))); + +/* Make sure that we don't accidentally use any normal C language built-in + type names in the first part of this file. Instead we want to use *only* + the type names defined above. The following macro definitions insure + that if we *do* accidentally use some normal C language built-in type name, + we will get a syntax error. */ + +#define char bogus_type +#define short bogus_type +#define int bogus_type +#define long bogus_type +#define unsigned bogus_type +#define float bogus_type +#define double bogus_type + +/* Versions prior to 3.4.4 were not taking into account the word size for + the 5 trapping arithmetic functions absv, addv, subv, mulv and negv. As + a consequence, the si and di variants were always and the only ones emitted. + To maintain backward compatibility, COMPAT_SIMODE_TRAPPING_ARITHMETIC is + defined on platforms where it makes sense to still have the si variants + emitted. As a bonus, their implementation is now correct. Note that the + same mechanism should have been implemented for the di variants, but it + turns out that no platform would define COMPAT_DIMODE_TRAPPING_ARITHMETIC + if it existed. */ + +#if LIBGCC2_UNITS_PER_WORD == 8 +#define W_TYPE_SIZE (8 * BITS_PER_UNIT) +#define Wtype DItype +#define UWtype UDItype +#define HWtype DItype +#define UHWtype UDItype +#define DWtype TItype +#define UDWtype UTItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## di ## b +#define __NDW(a,b) __gnu_ ## a ## ti ## b +#else +#define __NW(a,b) __ ## a ## di ## b +#define __NDW(a,b) __ ## a ## ti ## b +#endif +#define COMPAT_SIMODE_TRAPPING_ARITHMETIC +#elif LIBGCC2_UNITS_PER_WORD == 4 +#define W_TYPE_SIZE (4 * BITS_PER_UNIT) +#define Wtype SItype +#define UWtype USItype +#define HWtype SItype +#define UHWtype USItype +#define DWtype DItype +#define UDWtype UDItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## si ## b +#define __NDW(a,b) __gnu_ ## a ## di ## b +#else +#define __NW(a,b) __ ## a ## si ## b +#define __NDW(a,b) __ ## a ## di ## b +#endif +#elif LIBGCC2_UNITS_PER_WORD == 2 +#define W_TYPE_SIZE (2 * BITS_PER_UNIT) +#define Wtype HItype +#define UWtype UHItype +#define HWtype HItype +#define UHWtype UHItype +#define DWtype SItype +#define UDWtype USItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## hi ## b +#define __NDW(a,b) __gnu_ ## a ## si ## b +#else +#define __NW(a,b) __ ## a ## hi ## b +#define __NDW(a,b) __ ## a ## si ## b +#endif +#else +#define W_TYPE_SIZE BITS_PER_UNIT +#define Wtype QItype +#define UWtype UQItype +#define HWtype QItype +#define UHWtype UQItype +#define DWtype HItype +#define UDWtype UHItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## qi ## b +#define __NDW(a,b) __gnu_ ## a ## hi ## b +#else +#define __NW(a,b) __ ## a ## qi ## b +#define __NDW(a,b) __ ## a ## hi ## b +#endif +#endif + +#ifdef LIBGCC2_GNU_PREFIX +#define __N(a) __gnu_ ## a +#else +#define __N(a) __ ## a +#endif +#define Wtype_MAX ((Wtype)(((UWtype)1 << (W_TYPE_SIZE - 1)) - 1)) +#define Wtype_MIN (- Wtype_MAX - 1) + +#if W_TYPE_SIZE == 8 +# define Wtype_MAXp1_F 0x1p8f +#elif W_TYPE_SIZE == 16 +# define Wtype_MAXp1_F 0x1p16f +#elif W_TYPE_SIZE == 32 +# define Wtype_MAXp1_F 0x1p32f +#elif W_TYPE_SIZE == 64 +# define Wtype_MAXp1_F 0x1p64f +#else +# error "expand the table" +#endif + +#define __muldi3 __NDW(mul,3) +#define __divdi3 __NDW(div,3) +#define __udivdi3 __NDW(udiv,3) +#define __moddi3 __NDW(mod,3) +#define __umoddi3 __NDW(umod,3) +#define __negdi2 __NDW(neg,2) +#define __lshrdi3 __NDW(lshr,3) +#define __ashldi3 __NDW(ashl,3) +#define __ashrdi3 __NDW(ashr,3) +#define __cmpdi2 __NDW(cmp,2) +#define __ucmpdi2 __NDW(ucmp,2) +#define __udivmoddi4 __NDW(udivmod,4) +#define __fixunstfDI __NDW(fixunstf,) +#define __fixtfdi __NDW(fixtf,) +#define __fixunsxfDI __NDW(fixunsxf,) +#define __fixxfdi __NDW(fixxf,) +#define __fixunsdfDI __NDW(fixunsdf,) +#define __fixdfdi __NDW(fixdf,) +#define __fixunssfDI __NDW(fixunssf,) +#define __fixsfdi __NDW(fixsf,) +#define __floatdixf __NDW(float,xf) +#define __floatditf __NDW(float,tf) +#define __floatdidf __NDW(float,df) +#define __floatdisf __NDW(float,sf) +#define __floatundixf __NDW(floatun,xf) +#define __floatunditf __NDW(floatun,tf) +#define __floatundidf __NDW(floatun,df) +#define __floatundisf __NDW(floatun,sf) +#define __fixunsxfSI __NW(fixunsxf,) +#define __fixunstfSI __NW(fixunstf,) +#define __fixunsdfSI __NW(fixunsdf,) +#define __fixunssfSI __NW(fixunssf,) + +#define __absvSI2 __NW(absv,2) +#define __addvSI3 __NW(addv,3) +#define __subvSI3 __NW(subv,3) +#define __mulvSI3 __NW(mulv,3) +#define __negvSI2 __NW(negv,2) +#define __absvDI2 __NDW(absv,2) +#define __addvDI3 __NDW(addv,3) +#define __subvDI3 __NDW(subv,3) +#define __mulvDI3 __NDW(mulv,3) +#define __negvDI2 __NDW(negv,2) + +#define __ffsSI2 __NW(ffs,2) +#define __clzSI2 __NW(clz,2) +#define __ctzSI2 __NW(ctz,2) +#define __clrsbSI2 __NW(clrsb,2) +#define __popcountSI2 __NW(popcount,2) +#define __paritySI2 __NW(parity,2) +#define __ffsDI2 __NDW(ffs,2) +#define __clzDI2 __NDW(clz,2) +#define __ctzDI2 __NDW(ctz,2) +#define __clrsbDI2 __NDW(clrsb,2) +#define __popcountDI2 __NDW(popcount,2) +#define __parityDI2 __NDW(parity,2) + +#define __clz_tab __N(clz_tab) +#define __bswapsi2 __N(bswapsi2) +#define __bswapdi2 __N(bswapdi2) +#define __udiv_w_sdiv __N(udiv_w_sdiv) +#define __clear_cache __N(clear_cache) +#define __enable_execute_stack __N(enable_execute_stack) + +#ifndef __powisf2 +#define __powisf2 __N(powisf2) +#endif +#ifndef __powidf2 +#define __powidf2 __N(powidf2) +#endif +#ifndef __powitf2 +#define __powitf2 __N(powitf2) +#endif +#ifndef __powixf2 +#define __powixf2 __N(powixf2) +#endif +#ifndef __mulsc3 +#define __mulsc3 __N(mulsc3) +#endif +#ifndef __muldc3 +#define __muldc3 __N(muldc3) +#endif +#ifndef __mulxc3 +#define __mulxc3 __N(mulxc3) +#endif +#ifndef __multc3 +#define __multc3 __N(multc3) +#endif +#ifndef __divsc3 +#define __divsc3 __N(divsc3) +#endif +#ifndef __divdc3 +#define __divdc3 __N(divdc3) +#endif +#ifndef __divxc3 +#define __divxc3 __N(divxc3) +#endif +#ifndef __divtc3 +#define __divtc3 __N(divtc3) +#endif + +extern DWtype __muldi3 (DWtype, DWtype); +extern DWtype __divdi3 (DWtype, DWtype); +extern UDWtype __udivdi3 (UDWtype, UDWtype); +extern UDWtype __umoddi3 (UDWtype, UDWtype); +extern DWtype __moddi3 (DWtype, DWtype); + +/* __udivmoddi4 is static inline when building other libgcc2 portions. */ +#if (!defined (L_udivdi3) && !defined (L_divdi3) && \ + !defined (L_umoddi3) && !defined (L_moddi3)) +extern UDWtype __udivmoddi4 (UDWtype, UDWtype, UDWtype *); +#endif + +/* __negdi2 is static inline when building other libgcc2 portions. */ +#if !defined(L_divdi3) && !defined(L_moddi3) +extern DWtype __negdi2 (DWtype); +#endif + +extern DWtype __lshrdi3 (DWtype, shift_count_type); +extern DWtype __ashldi3 (DWtype, shift_count_type); +extern DWtype __ashrdi3 (DWtype, shift_count_type); + +/* __udiv_w_sdiv is static inline when building other libgcc2 portions. */ +#if (!defined(L_udivdi3) && !defined(L_divdi3) && \ + !defined(L_umoddi3) && !defined(L_moddi3)) +extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype); +#endif + +extern cmp_return_type __cmpdi2 (DWtype, DWtype); +extern cmp_return_type __ucmpdi2 (DWtype, DWtype); + +#if MIN_UNITS_PER_WORD > 1 +extern SItype __bswapsi2 (SItype); +#endif +#if __SIZEOF_LONG_LONG__ > 4 +extern DItype __bswapdi2 (DItype); +#endif + +extern Wtype __absvSI2 (Wtype); +extern Wtype __addvSI3 (Wtype, Wtype); +extern Wtype __subvSI3 (Wtype, Wtype); +extern Wtype __mulvSI3 (Wtype, Wtype); +extern Wtype __negvSI2 (Wtype); +extern DWtype __absvDI2 (DWtype); +extern DWtype __addvDI3 (DWtype, DWtype); +extern DWtype __subvDI3 (DWtype, DWtype); +extern DWtype __mulvDI3 (DWtype, DWtype); +extern DWtype __negvDI2 (DWtype); + +#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC +#define __absvsi2 __N(absvsi2) +#define __negvsi2 __N(negvsi2) +#define __addvsi3 __N(addvsi3) +#define __subvsi3 __N(subvsi3) +#define __mulvsi3 __N(mulvsi3) + +extern SItype __absvsi2 (SItype); +extern SItype __addvsi3 (SItype, SItype); +extern SItype __subvsi3 (SItype, SItype); +extern SItype __mulvsi3 (SItype, SItype); +extern SItype __negvsi2 (SItype); +#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ + +#undef int +#if LIBGCC2_HAS_SF_MODE +extern DWtype __fixsfdi (SFtype); +extern SFtype __floatdisf (DWtype); +extern SFtype __floatundisf (UDWtype); +extern UWtype __fixunssfSI (SFtype); +extern UDWtype __fixunssfDI (SFtype); +extern SFtype __powisf2 (SFtype, int); +extern SCtype __divsc3 (SFtype, SFtype, SFtype, SFtype); +extern SCtype __mulsc3 (SFtype, SFtype, SFtype, SFtype); +#endif +#if LIBGCC2_HAS_DF_MODE +extern DWtype __fixdfdi (DFtype); +extern DFtype __floatdidf (DWtype); +extern DFtype __floatundidf (UDWtype); +extern UWtype __fixunsdfSI (DFtype); +extern UDWtype __fixunsdfDI (DFtype); +extern DFtype __powidf2 (DFtype, int); +extern DCtype __divdc3 (DFtype, DFtype, DFtype, DFtype); +extern DCtype __muldc3 (DFtype, DFtype, DFtype, DFtype); +#endif + +#if LIBGCC2_HAS_XF_MODE +extern DWtype __fixxfdi (XFtype); +extern UDWtype __fixunsxfDI (XFtype); +extern XFtype __floatdixf (DWtype); +extern XFtype __floatundixf (UDWtype); +extern UWtype __fixunsxfSI (XFtype); +extern XFtype __powixf2 (XFtype, int); +extern XCtype __divxc3 (XFtype, XFtype, XFtype, XFtype); +extern XCtype __mulxc3 (XFtype, XFtype, XFtype, XFtype); +#endif + +#if LIBGCC2_HAS_TF_MODE +extern UDWtype __fixunstfDI (TFtype); +extern DWtype __fixtfdi (TFtype); +extern TFtype __floatditf (DWtype); +extern TFtype __floatunditf (UDWtype); +extern TFtype __powitf2 (TFtype, int); +extern TCtype __divtc3 (TFtype, TFtype, TFtype, TFtype); +extern TCtype __multc3 (TFtype, TFtype, TFtype, TFtype); +#endif +#define int bogus_type + +/* DWstructs are pairs of Wtype values in the order determined by + __BYTE_ORDER__. */ + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + struct DWstruct {Wtype high, low;}; +#else + struct DWstruct {Wtype low, high;}; +#endif + +/* We need this union to unpack/pack DImode values, since we don't have + any arithmetic yet. Incoming DImode parameters are stored into the + `ll' field, and the unpacked result is read from the struct `s'. */ + +typedef union +{ + struct DWstruct s; + DWtype ll; +} DWunion; + +/* Defined for L_popcount_tab. Exported here because some targets may + want to use it for their own versions of the __popcount builtins. */ +extern const UQItype __popcount_tab[256]; + +/* Defined for L_clz. Exported here because some targets may want to use + it for their own versions of the __clz builtins. It contains the bit + position of the first set bit for the numbers 0 - 255. This avoids the + need for a separate table for the __ctz builtins. */ +extern const UQItype __clz_tab[256]; + +#include "longlong.h" + +#undef int +extern int __clzDI2 (UDWtype); +extern int __clzSI2 (UWtype); +extern int __ctzSI2 (UWtype); +extern int __ctzDI2 (UDWtype); +extern int __clrsbSI2 (Wtype); +extern int __clrsbDI2 (DWtype); +extern int __ffsSI2 (UWtype); +extern int __ffsDI2 (DWtype); +extern int __popcountSI2 (UWtype); +extern int __popcountDI2 (UDWtype); +extern int __paritySI2 (UWtype); +extern int __parityDI2 (UDWtype); +#define int bogus_type + +extern void __enable_execute_stack (void *); + +#ifndef HIDE_EXPORTS +#pragma GCC visibility pop +#endif + +#endif /* ! GCC_LIBGCC2_H */ diff --git a/libgcc/longlong.h b/libgcc/longlong.h new file mode 100644 index 0000000..30cc2e3 --- /dev/null +++ b/libgcc/longlong.h @@ -0,0 +1,1660 @@ +/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. + Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* You have to define the following before including this file: + + UWtype -- An unsigned type, default type for operations (typically a "word") + UHWtype -- An unsigned type, at least half the size of UWtype. + UDWtype -- An unsigned type, at least twice as large a UWtype + W_TYPE_SIZE -- size in bits of UWtype + + UQItype -- Unsigned 8 bit type. + SItype, USItype -- Signed and unsigned 32 bit types. + DItype, UDItype -- Signed and unsigned 64 bit types. + + On a 32 bit machine UWtype should typically be USItype; + on a 64 bit machine, UWtype should typically be UDItype. */ + +#define __BITS4 (W_TYPE_SIZE / 4) +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) + +#ifndef W_TYPE_SIZE +#define W_TYPE_SIZE 32 +#define UWtype USItype +#define UHWtype USItype +#define UDWtype UDItype +#endif + +/* Used in glibc only. */ +#ifndef attribute_hidden +#define attribute_hidden +#endif + +extern const UQItype __clz_tab[256] attribute_hidden; + +/* Define auxiliary asm macros. + + 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two + UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype + word product in HIGH_PROD and LOW_PROD. + + 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a + UDWtype product. This is just a variant of umul_ppmm. + + 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator) divides a UDWtype, composed by the UWtype integers + HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient + in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less + than DENOMINATOR for correct operation. If, in addition, the most + significant bit of DENOMINATOR must be 1, then the pre-processor symbol + UDIV_NEEDS_NORMALIZATION is defined to 1. + + 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator). Like udiv_qrnnd but the numbers are signed. The quotient + is rounded towards 0. + + 5) count_leading_zeros(count, x) counts the number of zero-bits from the + msb to the first nonzero bit in the UWtype X. This is the number of + steps X needs to be shifted left to set the msb. Undefined for X == 0, + unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. + + 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts + from the least significant end. + + 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, + high_addend_2, low_addend_2) adds two UWtype integers, composed by + HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 + respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow + (i.e. carry out) is not stored anywhere, and is lost. + + 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, + high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, + composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and + LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE + and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, + and is lost. + + If any of these macros are left undefined for a particular CPU, + C macros are used. */ + +/* The CPUs come in alphabetical order below. + + Please add support for more CPUs here, or improve the current support + for the CPUs below! + (E.g. WE32100, IBM360.) */ + +#if defined (__GNUC__) && !defined (NO_ASM) + +/* We sometimes need to clobber "cc" with gcc2, but that would not be + understood by gcc1. Use cpp to avoid major code duplication. */ +#if __GNUC__ < 2 +#define __CLOBBER_CC +#define __AND_CLOBBER_CC +#else /* __GNUC__ >= 2 */ +#define __CLOBBER_CC : "cc" +#define __AND_CLOBBER_CC , "cc" +#endif /* __GNUC__ < 2 */ + +#if defined (__alpha) && W_TYPE_SIZE == 64 +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ + (ph) = __builtin_alpha_umulh (__m0, __m1); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 46 +#ifndef LONGLONG_STANDALONE +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { UDItype __r; \ + (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ + (r) = __r; \ + } while (0) +extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); +#define UDIV_TIME 220 +#endif /* LONGLONG_STANDALONE */ +#ifdef __alpha_cix__ +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) +#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) +#define COUNT_LEADING_ZEROS_0 64 +#else +#define count_leading_zeros(COUNT,X) \ + do { \ + UDItype __xr = (X), __t, __a; \ + __t = __builtin_alpha_cmpbge (0, __xr); \ + __a = __clz_tab[__t ^ 0xff] - 1; \ + __t = __builtin_alpha_extbl (__xr, __a); \ + (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ + } while (0) +#define count_trailing_zeros(COUNT,X) \ + do { \ + UDItype __xr = (X), __t, __a; \ + __t = __builtin_alpha_cmpbge (0, __xr); \ + __t = ~__t & -~__t; \ + __a = ((__t & 0xCC) != 0) * 2; \ + __a += ((__t & 0xF0) != 0) * 4; \ + __a += ((__t & 0xAA) != 0); \ + __t = __builtin_alpha_extbl (__xr, __a); \ + __a <<= 3; \ + __t &= -__t; \ + __a += ((__t & 0xCC) != 0) * 2; \ + __a += ((__t & 0xF0) != 0) * 4; \ + __a += ((__t & 0xAA) != 0); \ + (COUNT) = __a; \ + } while (0) +#endif /* __alpha_cix__ */ +#endif /* __alpha */ + +#if defined (__arc__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rIJ" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rIJ" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rIJ" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rIJ" ((USItype) (bl))) +/* Call libgcc routine. */ +#define umul_ppmm(w1, w0, u, v) \ +do { \ + DWunion __w; \ + __w.ll = __umulsidi3 (u, v); \ + w1 = __w.s.high; \ + w0 = __w.s.low; \ +} while (0) +#define __umulsidi3 __umulsidi3 +UDItype __umulsidi3 (USItype, USItype); +#endif + +#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rI" ((USItype) (bl)) __CLOBBER_CC) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rI" ((USItype) (bl)) __CLOBBER_CC) +#define umul_ppmm(xh, xl, a, b) \ +{register USItype __t0, __t1, __t2; \ + __asm__ ("%@ Inlined umul_ppmm\n" \ + " mov %2, %5, lsr #16\n" \ + " mov %0, %6, lsr #16\n" \ + " bic %3, %5, %2, lsl #16\n" \ + " bic %4, %6, %0, lsl #16\n" \ + " mul %1, %3, %4\n" \ + " mul %4, %2, %4\n" \ + " mul %3, %0, %3\n" \ + " mul %0, %2, %0\n" \ + " adds %3, %4, %3\n" \ + " addcs %0, %0, #65536\n" \ + " adds %1, %1, %3, lsl #16\n" \ + " adc %0, %0, %3, lsr #16" \ + : "=&r" ((USItype) (xh)), \ + "=r" ((USItype) (xl)), \ + "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ + : "r" ((USItype) (a)), \ + "r" ((USItype) (b)) __CLOBBER_CC );} +#define UMUL_TIME 20 +#define UDIV_TIME 100 +#endif /* __arm__ */ + +#if defined(__arm__) +/* Let gcc decide how best to implement count_leading_zeros. */ +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) +#define COUNT_LEADING_ZEROS_0 32 +#endif + +#if defined (__AVR__) + +#if W_TYPE_SIZE == 16 +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) +#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctz (X)) +#define COUNT_LEADING_ZEROS_0 16 +#endif /* W_TYPE_SIZE == 16 */ + +#if W_TYPE_SIZE == 32 +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) +#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) +#define COUNT_LEADING_ZEROS_0 32 +#endif /* W_TYPE_SIZE == 32 */ + +#if W_TYPE_SIZE == 64 +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzll (X)) +#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzll (X)) +#define COUNT_LEADING_ZEROS_0 64 +#endif /* W_TYPE_SIZE == 64 */ + +#endif /* defined (__AVR__) */ + +#if defined (__CRIS__) && __CRIS_arch_version >= 3 +#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) +#if __CRIS_arch_version >= 8 +#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) +#endif +#endif /* __CRIS__ */ + +#if defined (__hppa) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rM" ((USItype) (ah)), \ + "rM" ((USItype) (bh)), \ + "%rM" ((USItype) (al)), \ + "rM" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rM" ((USItype) (ah)), \ + "rM" ((USItype) (bh)), \ + "rM" ((USItype) (al)), \ + "rM" ((USItype) (bl))) +#if defined (_PA_RISC1_1) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + union \ + { \ + UDItype __f; \ + struct {USItype __w1, __w0;} __w1w0; \ + } __t; \ + __asm__ ("xmpyu %1,%2,%0" \ + : "=x" (__t.__f) \ + : "x" ((USItype) (u)), \ + "x" ((USItype) (v))); \ + (w1) = __t.__w1w0.__w1; \ + (w0) = __t.__w1w0.__w0; \ + } while (0) +#define UMUL_TIME 8 +#else +#define UMUL_TIME 30 +#endif +#define UDIV_TIME 40 +#define count_leading_zeros(count, x) \ + do { \ + USItype __tmp; \ + __asm__ ( \ + "ldi 1,%0\n" \ +" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ +" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ +" ldo 16(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ +" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ +" ldo 8(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ +" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ +" ldo 4(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ +" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ +" ldo 2(%0),%0 ; Yes. Perform add.\n" \ +" extru %1,30,1,%1 ; Extract bit 1.\n" \ +" sub %0,%1,%0 ; Subtract it.\n" \ + : "=r" (count), "=r" (__tmp) : "1" (x)); \ + } while (0) +#endif + +#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32 +#if !defined (__zarch__) +#define smul_ppmm(xh, xl, m0, m1) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __x; \ + __asm__ ("lr %N0,%1\n\tmr %0,%2" \ + : "=&r" (__x.__ll) \ + : "r" (m0), "r" (m1)); \ + (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __x; \ + __x.__i.__h = n1; __x.__i.__l = n0; \ + __asm__ ("dr %0,%2" \ + : "=r" (__x.__ll) \ + : "0" (__x.__ll), "r" (d)); \ + (q) = __x.__i.__l; (r) = __x.__i.__h; \ + } while (0) +#else +#define smul_ppmm(xh, xl, m0, m1) \ + do { \ + register SItype __r0 __asm__ ("0"); \ + register SItype __r1 __asm__ ("1") = (m0); \ + \ + __asm__ ("mr\t%%r0,%3" \ + : "=r" (__r0), "=r" (__r1) \ + : "r" (__r1), "r" (m1)); \ + (xh) = __r0; (xl) = __r1; \ + } while (0) + +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + register SItype __r0 __asm__ ("0") = (n1); \ + register SItype __r1 __asm__ ("1") = (n0); \ + \ + __asm__ ("dr\t%%r0,%4" \ + : "=r" (__r0), "=r" (__r1) \ + : "r" (__r0), "r" (__r1), "r" (d)); \ + (q) = __r1; (r) = __r0; \ + } while (0) +#endif /* __zarch__ */ +#endif + +#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add{l} {%5,%1|%1,%5}\n\tadc{l} {%3,%0|%0,%3}" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub{l} {%5,%1|%1,%5}\n\tsbb{l} {%3,%0|%0,%3}" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mul{l} %3" \ + : "=a" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "rm" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, dv) \ + __asm__ ("div{l} %4" \ + : "=a" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "rm" ((USItype) (dv))) +#define count_leading_zeros(count, x) ((count) = __builtin_clz (x)) +#define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x)) +#define UMUL_TIME 40 +#define UDIV_TIME 40 +#endif /* 80x86 */ + +#if (defined (__x86_64__) || defined (__i386__)) && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add{q} {%5,%1|%1,%5}\n\tadc{q} {%3,%0|%0,%3}" \ + : "=r" ((UDItype) (sh)), \ + "=&r" ((UDItype) (sl)) \ + : "%0" ((UDItype) (ah)), \ + "rme" ((UDItype) (bh)), \ + "%1" ((UDItype) (al)), \ + "rme" ((UDItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub{q} {%5,%1|%1,%5}\n\tsbb{q} {%3,%0|%0,%3}" \ + : "=r" ((UDItype) (sh)), \ + "=&r" ((UDItype) (sl)) \ + : "0" ((UDItype) (ah)), \ + "rme" ((UDItype) (bh)), \ + "1" ((UDItype) (al)), \ + "rme" ((UDItype) (bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mul{q} %3" \ + : "=a" ((UDItype) (w0)), \ + "=d" ((UDItype) (w1)) \ + : "%0" ((UDItype) (u)), \ + "rm" ((UDItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, dv) \ + __asm__ ("div{q} %4" \ + : "=a" ((UDItype) (q)), \ + "=d" ((UDItype) (r)) \ + : "0" ((UDItype) (n0)), \ + "1" ((UDItype) (n1)), \ + "rm" ((UDItype) (dv))) +#define count_leading_zeros(count, x) ((count) = __builtin_clzll (x)) +#define count_trailing_zeros(count, x) ((count) = __builtin_ctzll (x)) +#define UMUL_TIME 40 +#define UDIV_TIME 40 +#endif /* x86_64 */ + +#if defined (__i960__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__xx.__ll) \ + : "%dI" ((USItype) (u)), \ + "dI" ((USItype) (v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__w) \ + : "%dI" ((USItype) (u)), \ + "dI" ((USItype) (v))); \ + __w; }) +#endif /* __i960__ */ + +#if defined (__ia64) && W_TYPE_SIZE == 64 +/* This form encourages gcc (pre-release 3.4 at least) to emit predicated + "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency. The generic + code using "al<bl" arithmetically comes out making an actual 0 or 1 in a + register, which takes an extra cycle. */ +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) - (bl); \ + if ((al) < (bl)) \ + (sh) = (ah) - (bh) - 1; \ + else \ + (sh) = (ah) - (bh); \ + (sl) = __x; \ + } while (0) + +/* Do both product parts in assembly, since that gives better code with + all gcc versions. Some callers will just use the upper part, and in + that situation we waste an instruction, but not any cycles. */ +#define umul_ppmm(ph, pl, m0, m1) \ + __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0" \ + : "=&f" (ph), "=f" (pl) \ + : "f" (m0), "f" (m1)) +#define count_leading_zeros(count, x) \ + do { \ + UWtype _x = (x), _y, _a, _c; \ + __asm__ ("mux1 %0 = %1, @rev" : "=r" (_y) : "r" (_x)); \ + __asm__ ("czx1.l %0 = %1" : "=r" (_a) : "r" (-_y | _y)); \ + _c = (_a - 1) << 3; \ + _x >>= _c; \ + if (_x >= 1 << 4) \ + _x >>= 4, _c += 4; \ + if (_x >= 1 << 2) \ + _x >>= 2, _c += 2; \ + _c += _x >> 1; \ + (count) = W_TYPE_SIZE - 1 - _c; \ + } while (0) +/* similar to what gcc does for __builtin_ffs, but 0 based rather than 1 + based, and we don't need a special case for x==0 here */ +#define count_trailing_zeros(count, x) \ + do { \ + UWtype __ctz_x = (x); \ + __asm__ ("popcnt %0 = %1" \ + : "=r" (count) \ + : "r" ((__ctz_x-1) & ~__ctz_x)); \ + } while (0) +#define UMUL_TIME 14 +#endif + +#if defined (__M32R__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + /* The cmp clears the condition bit. */ \ + __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl)) \ + : "cbit") +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + /* The cmp clears the condition bit. */ \ + __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl)) \ + : "cbit") +#endif /* __M32R__ */ + +#if defined (__mc68000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ + : "=d" ((USItype) (sh)), \ + "=&d" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "d" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ + : "=d" ((USItype) (sh)), \ + "=&d" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "d" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) + +/* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r. */ +#if (defined (__mc68020__) && !defined (__mc68060__)) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulu%.l %3,%1:%0" \ + : "=d" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "dmi" ((USItype) (v))) +#define UMUL_TIME 45 +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divu%.l %4,%1:%0" \ + : "=d" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "dmi" ((USItype) (d))) +#define UDIV_TIME 90 +#define sdiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divs%.l %4,%1:%0" \ + : "=d" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "dmi" ((USItype) (d))) + +#elif defined (__mcoldfire__) /* not mc68020 */ + +#define umul_ppmm(xh, xl, a, b) \ + __asm__ ("| Inlined umul_ppmm\n" \ + " move%.l %2,%/d0\n" \ + " move%.l %3,%/d1\n" \ + " move%.l %/d0,%/d2\n" \ + " swap %/d0\n" \ + " move%.l %/d1,%/d3\n" \ + " swap %/d1\n" \ + " move%.w %/d2,%/d4\n" \ + " mulu %/d3,%/d4\n" \ + " mulu %/d1,%/d2\n" \ + " mulu %/d0,%/d3\n" \ + " mulu %/d0,%/d1\n" \ + " move%.l %/d4,%/d0\n" \ + " clr%.w %/d0\n" \ + " swap %/d0\n" \ + " add%.l %/d0,%/d2\n" \ + " add%.l %/d3,%/d2\n" \ + " jcc 1f\n" \ + " add%.l %#65536,%/d1\n" \ + "1: swap %/d2\n" \ + " moveq %#0,%/d0\n" \ + " move%.w %/d2,%/d0\n" \ + " move%.w %/d4,%/d2\n" \ + " move%.l %/d2,%1\n" \ + " add%.l %/d1,%/d0\n" \ + " move%.l %/d0,%0" \ + : "=g" ((USItype) (xh)), \ + "=g" ((USItype) (xl)) \ + : "g" ((USItype) (a)), \ + "g" ((USItype) (b)) \ + : "d0", "d1", "d2", "d3", "d4") +#define UMUL_TIME 100 +#define UDIV_TIME 400 +#else /* not ColdFire */ +/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ +#define umul_ppmm(xh, xl, a, b) \ + __asm__ ("| Inlined umul_ppmm\n" \ + " move%.l %2,%/d0\n" \ + " move%.l %3,%/d1\n" \ + " move%.l %/d0,%/d2\n" \ + " swap %/d0\n" \ + " move%.l %/d1,%/d3\n" \ + " swap %/d1\n" \ + " move%.w %/d2,%/d4\n" \ + " mulu %/d3,%/d4\n" \ + " mulu %/d1,%/d2\n" \ + " mulu %/d0,%/d3\n" \ + " mulu %/d0,%/d1\n" \ + " move%.l %/d4,%/d0\n" \ + " eor%.w %/d0,%/d0\n" \ + " swap %/d0\n" \ + " add%.l %/d0,%/d2\n" \ + " add%.l %/d3,%/d2\n" \ + " jcc 1f\n" \ + " add%.l %#65536,%/d1\n" \ + "1: swap %/d2\n" \ + " moveq %#0,%/d0\n" \ + " move%.w %/d2,%/d0\n" \ + " move%.w %/d4,%/d2\n" \ + " move%.l %/d2,%1\n" \ + " add%.l %/d1,%/d0\n" \ + " move%.l %/d0,%0" \ + : "=g" ((USItype) (xh)), \ + "=g" ((USItype) (xl)) \ + : "g" ((USItype) (a)), \ + "g" ((USItype) (b)) \ + : "d0", "d1", "d2", "d3", "d4") +#define UMUL_TIME 100 +#define UDIV_TIME 400 + +#endif /* not mc68020 */ + +/* The '020, '030, '040 and '060 have bitfield insns. + cpu32 disguises as a 68020, but lacks them. */ +#if defined (__mc68020__) && !defined (__mcpu32__) +#define count_leading_zeros(count, x) \ + __asm__ ("bfffo %1{%b2:%b2},%0" \ + : "=d" ((USItype) (count)) \ + : "od" ((USItype) (x)), "n" (0)) +/* Some ColdFire architectures have a ff1 instruction supported via + __builtin_clz. */ +#elif defined (__mcfisaaplus__) || defined (__mcfisac__) +#define count_leading_zeros(count,x) ((count) = __builtin_clz (x)) +#define COUNT_LEADING_ZEROS_0 32 +#endif +#endif /* mc68000 */ + +#if defined (__m88000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rJ" ((USItype) (ah)), \ + "rJ" ((USItype) (bh)), \ + "%rJ" ((USItype) (al)), \ + "rJ" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rJ" ((USItype) (ah)), \ + "rJ" ((USItype) (bh)), \ + "rJ" ((USItype) (al)), \ + "rJ" ((USItype) (bl))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("ff1 %0,%1" \ + : "=r" (__cbtmp) \ + : "r" ((USItype) (x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#define COUNT_LEADING_ZEROS_0 63 /* sic */ +#if defined (__mc88110__) +#define umul_ppmm(wh, wl, u, v) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("mulu.d %0,%1,%2" \ + : "=r" (__xx.__ll) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))); \ + (wh) = __xx.__i.__h; \ + (wl) = __xx.__i.__l; \ + } while (0) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + USItype __q; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("divu.d %0,%1,%2" \ + : "=r" (__q) \ + : "r" (__xx.__ll), \ + "r" ((USItype) (d))); \ + (r) = (n0) - __q * (d); (q) = __q; }) +#define UMUL_TIME 5 +#define UDIV_TIME 25 +#else +#define UMUL_TIME 17 +#define UDIV_TIME 150 +#endif /* __mc88110__ */ +#endif /* __m88000__ */ + +#if defined (__mn10300__) +# if defined (__AM33__) +# define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) +# define umul_ppmm(w1, w0, u, v) \ + asm("mulu %3,%2,%1,%0" : "=r"(w0), "=r"(w1) : "r"(u), "r"(v)) +# define smul_ppmm(w1, w0, u, v) \ + asm("mul %3,%2,%1,%0" : "=r"(w0), "=r"(w1) : "r"(u), "r"(v)) +# else +# define umul_ppmm(w1, w0, u, v) \ + asm("nop; nop; mulu %3,%0" : "=d"(w0), "=z"(w1) : "%0"(u), "d"(v)) +# define smul_ppmm(w1, w0, u, v) \ + asm("nop; nop; mul %3,%0" : "=d"(w0), "=z"(w1) : "%0"(u), "d"(v)) +# endif +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + DWunion __s, __a, __b; \ + __a.s.low = (al); __a.s.high = (ah); \ + __b.s.low = (bl); __b.s.high = (bh); \ + __s.ll = __a.ll + __b.ll; \ + (sl) = __s.s.low; (sh) = __s.s.high; \ + } while (0) +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + DWunion __s, __a, __b; \ + __a.s.low = (al); __a.s.high = (ah); \ + __b.s.low = (bl); __b.s.high = (bh); \ + __s.ll = __a.ll - __b.ll; \ + (sl) = __s.s.low; (sh) = __s.s.high; \ + } while (0) +# define udiv_qrnnd(q, r, nh, nl, d) \ + asm("divu %2,%0" : "=D"(q), "=z"(r) : "D"(d), "0"(nl), "1"(nh)) +# define sdiv_qrnnd(q, r, nh, nl, d) \ + asm("div %2,%0" : "=D"(q), "=z"(r) : "D"(d), "0"(nl), "1"(nh)) +# define UMUL_TIME 3 +# define UDIV_TIME 38 +#endif + +#if defined (__mips__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UDItype __x = (UDItype) (USItype) (u) * (USItype) (v); \ + (w1) = (USItype) (__x >> 32); \ + (w0) = (USItype) (__x); \ + } while (0) +#define UMUL_TIME 10 +#define UDIV_TIME 100 + +#if (__mips == 32 || __mips == 64) && ! __mips16 +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) +#define COUNT_LEADING_ZEROS_0 32 +#endif +#endif /* __mips__ */ + +#if defined (__ns32000__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("meid %2,%0" \ + : "=g" (__xx.__ll) \ + : "%0" ((USItype) (u)), \ + "g" ((USItype) (v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("meid %2,%0" \ + : "=g" (__w) \ + : "%0" ((USItype) (u)), \ + "g" ((USItype) (v))); \ + __w; }) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("deid %2,%0" \ + : "=g" (__xx.__ll) \ + : "0" (__xx.__ll), \ + "g" ((USItype) (d))); \ + (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) +#define count_trailing_zeros(count,x) \ + do { \ + __asm__ ("ffsd %2,%0" \ + : "=r" ((USItype) (count)) \ + : "0" ((USItype) 0), \ + "r" ((USItype) (x))); \ + } while (0) +#endif /* __ns32000__ */ + +/* FIXME: We should test _IBMR2 here when we add assembly support for the + system vendor compilers. + FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good + enough, since that hits ARM and m68k too. */ +#if (defined (_ARCH_PPC) /* AIX */ \ + || defined (_ARCH_PWR) /* AIX */ \ + || defined (_ARCH_COM) /* AIX */ \ + || defined (__powerpc__) /* gcc */ \ + || defined (__POWERPC__) /* BEOS */ \ + || defined (__ppc__) /* Darwin */ \ + || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ + || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ + && CPU_FAMILY == PPC) \ + ) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" (sh), "=&r" (sl) \ + : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" (sh), "=&r" (sl) \ + : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) +#define COUNT_LEADING_ZEROS_0 32 +#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ + || defined (__ppc__) \ + || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ + || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ + && CPU_FAMILY == PPC) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + SItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 +#define UDIV_TIME 120 +#elif defined (_ARCH_PWR) +#define UMUL_TIME 8 +#define smul_ppmm(xh, xl, m0, m1) \ + __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) +#define SMUL_TIME 4 +#define sdiv_qrnnd(q, r, nh, nl, d) \ + __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) +#define UDIV_TIME 100 +#endif +#endif /* 32-bit POWER architecture variants. */ + +/* We should test _IBMR2 here when we add assembly support for the system + vendor compilers. */ +#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" (sh), "=&r" (sl) \ + : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" (sh), "=&r" (sl) \ + : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) +#define COUNT_LEADING_ZEROS_0 64 +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + DItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 /* ??? */ +#define UDIV_TIME 120 /* ??? */ +#endif /* 64-bit PowerPC. */ + +#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("a %1,%5\n\tae %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "r" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("s %1,%5\n\tse %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl))) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ( \ + "s r2,r2\n" \ +" mts r10,%2\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" cas %0,r2,r0\n" \ +" mfs r10,%1" \ + : "=r" ((USItype) (ph)), \ + "=r" ((USItype) (pl)) \ + : "%r" (__m0), \ + "r" (__m1) \ + : "r2"); \ + (ph) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define UMUL_TIME 20 +#define UDIV_TIME 200 +#define count_leading_zeros(count, x) \ + do { \ + if ((x) >= 0x10000) \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x) >> 16)); \ + else \ + { \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x))); \ + (count) += 16; \ + } \ + } while (0) +#endif + +#if defined(__sh__) && !__SHMEDIA__ && W_TYPE_SIZE == 32 +#ifndef __sh1__ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ( \ + "dmulu.l %2,%3\n\tsts%M1 macl,%1\n\tsts%M0 mach,%0" \ + : "=r<" ((USItype)(w1)), \ + "=r<" ((USItype)(w0)) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v)) \ + : "macl", "mach") +#define UMUL_TIME 5 +#endif + +/* This is the same algorithm as __udiv_qrnnd_c. */ +#define UDIV_NEEDS_NORMALIZATION 1 + +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { \ + extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \ + __attribute__ ((visibility ("hidden"))); \ + /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \ + __asm__ ( \ + "mov%M4 %4,r5\n" \ +" swap.w %3,r4\n" \ +" swap.w r5,r6\n" \ +" jsr @%5\n" \ +" shll16 r6\n" \ +" swap.w r4,r4\n" \ +" jsr @%5\n" \ +" swap.w r1,%0\n" \ +" or r1,%0" \ + : "=r" (q), "=&z" (r) \ + : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \ + : "r1", "r2", "r4", "r5", "r6", "pr", "t"); \ + } while (0) + +#define UDIV_TIME 80 + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("clrt;subc %5,%1; subc %4,%0" \ + : "=r" (sh), "=r" (sl) \ + : "0" (ah), "1" (al), "r" (bh), "r" (bl) : "t") + +#endif /* __sh__ */ + +#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 +#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) +#define count_leading_zeros(count, x) \ + do \ + { \ + UDItype x_ = (USItype)(x); \ + SItype c_; \ + \ + __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ + (count) = c_ - 31; \ + } \ + while (0) +#define COUNT_LEADING_ZEROS_0 32 +#endif + +#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ + && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rJ" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%rJ" ((USItype) (al)), \ + "rI" ((USItype) (bl)) \ + __CLOBBER_CC) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rJ" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "rJ" ((USItype) (al)), \ + "rI" ((USItype) (bl)) \ + __CLOBBER_CC) +#if defined (__sparc_v8__) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))) +#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ + __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ + : "=&r" ((USItype) (__q)), \ + "=&r" ((USItype) (__r)) \ + : "r" ((USItype) (__n1)), \ + "r" ((USItype) (__n0)), \ + "r" ((USItype) (__d))) +#else +#if defined (__sparclite__) +/* This has hardware multiply but not divide. It also has two additional + instructions scan (ffs from high bit) and divscc. */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("! Inlined udiv_qrnnd\n" \ +" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ +" tst %%g0\n" \ +" divscc %3,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%0\n" \ +" rd %%y,%1\n" \ +" bl,a 1f\n" \ +" add %1,%4,%1\n" \ +"1: ! End of inline udiv_qrnnd" \ + : "=r" ((USItype) (q)), \ + "=r" ((USItype) (r)) \ + : "r" ((USItype) (n1)), \ + "r" ((USItype) (n0)), \ + "rI" ((USItype) (d)) \ + : "g1" __AND_CLOBBER_CC) +#define UDIV_TIME 37 +#define count_leading_zeros(count, x) \ + do { \ + __asm__ ("scan %1,1,%0" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x))); \ + } while (0) +/* Early sparclites return 63 for an argument of 0, but they warn that future + implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 + undefined. */ +#else +/* SPARC without integer multiplication and divide instructions. + (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("! Inlined umul_ppmm\n" \ +" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ +" sra %3,31,%%o5 ! Don't move this insn\n" \ +" and %2,%%o5,%%o5 ! Don't move this insn\n" \ +" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,0,%%g1\n" \ +" add %%g1,%%o5,%0\n" \ +" rd %%y,%1" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "%rI" ((USItype) (u)), \ + "r" ((USItype) (v)) \ + : "g1", "o5" __AND_CLOBBER_CC) +#define UMUL_TIME 39 /* 39 instructions */ +/* It's quite necessary to add this much assembler for the sparc. + The default udiv_qrnnd (in C) is more than 10 times slower! */ +#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ + __asm__ ("! Inlined udiv_qrnnd\n" \ +" mov 32,%%g1\n" \ +" subcc %1,%2,%%g0\n" \ +"1: bcs 5f\n" \ +" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +" sub %1,%2,%1 ! this kills msb of n\n" \ +" addx %1,%1,%1 ! so this can't give carry\n" \ +" subcc %%g1,1,%%g1\n" \ +"2: bne 1b\n" \ +" subcc %1,%2,%%g0\n" \ +" bcs 3f\n" \ +" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +" b 3f\n" \ +" sub %1,%2,%1 ! this kills msb of n\n" \ +"4: sub %1,%2,%1\n" \ +"5: addxcc %1,%1,%1\n" \ +" bcc 2b\n" \ +" subcc %%g1,1,%%g1\n" \ +"! Got carry from n. Subtract next step to cancel this carry.\n" \ +" bne 4b\n" \ +" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ +" sub %1,%2,%1\n" \ +"3: xnor %0,0,%0\n" \ +" ! End of inline udiv_qrnnd" \ + : "=&r" ((USItype) (__q)), \ + "=&r" ((USItype) (__r)) \ + : "r" ((USItype) (__d)), \ + "1" ((USItype) (__n1)), \ + "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) +#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ +#endif /* __sparclite__ */ +#endif /* __sparc_v8__ */ +#endif /* sparc32 */ + +#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ + && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1\n\t" \ + "add %r2,%3,%0\n\t" \ + "bcs,a,pn %%xcc, 1f\n\t" \ + "add %0, 1, %0\n" \ + "1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "%rJ" ((UDItype)(ah)), \ + "rI" ((UDItype)(bh)), \ + "%rJ" ((UDItype)(al)), \ + "rI" ((UDItype)(bl)) \ + __CLOBBER_CC) + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1\n\t" \ + "sub %r2,%3,%0\n\t" \ + "bcs,a,pn %%xcc, 1f\n\t" \ + "sub %0, 1, %0\n\t" \ + "1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "rJ" ((UDItype)(ah)), \ + "rI" ((UDItype)(bh)), \ + "rJ" ((UDItype)(al)), \ + "rI" ((UDItype)(bl)) \ + __CLOBBER_CC) + +#define umul_ppmm(wh, wl, u, v) \ + do { \ + UDItype tmp1, tmp2, tmp3, tmp4; \ + __asm__ __volatile__ ( \ + "srl %7,0,%3\n\t" \ + "mulx %3,%6,%1\n\t" \ + "srlx %6,32,%2\n\t" \ + "mulx %2,%3,%4\n\t" \ + "sllx %4,32,%5\n\t" \ + "srl %6,0,%3\n\t" \ + "sub %1,%5,%5\n\t" \ + "srlx %5,32,%5\n\t" \ + "addcc %4,%5,%4\n\t" \ + "srlx %7,32,%5\n\t" \ + "mulx %3,%5,%3\n\t" \ + "mulx %2,%5,%5\n\t" \ + "sethi %%hi(0x80000000),%2\n\t" \ + "addcc %4,%3,%4\n\t" \ + "srlx %4,32,%4\n\t" \ + "add %2,%2,%2\n\t" \ + "movcc %%xcc,%%g0,%2\n\t" \ + "addcc %5,%4,%5\n\t" \ + "sllx %3,32,%3\n\t" \ + "add %1,%3,%1\n\t" \ + "add %5,%2,%0" \ + : "=r" ((UDItype)(wh)), \ + "=&r" ((UDItype)(wl)), \ + "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ + : "r" ((UDItype)(u)), \ + "r" ((UDItype)(v)) \ + __CLOBBER_CC); \ + } while (0) +#define UMUL_TIME 96 +#define UDIV_TIME 230 +#endif /* sparc64 */ + +#if defined (__vax__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ + : "=g" ((USItype) (sh)), \ + "=&g" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ + : "=g" ((USItype) (sh)), \ + "=&g" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union { \ + UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("emul %1,%2,$0,%0" \ + : "=r" (__xx.__ll) \ + : "g" (__m0), \ + "g" (__m1)); \ + (xh) = __xx.__i.__h; \ + (xl) = __xx.__i.__l; \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {SItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = n1; __xx.__i.__l = n0; \ + __asm__ ("ediv %3,%2,%0,%1" \ + : "=g" (q), "=g" (r) \ + : "g" (__xx.__ll), "g" (d)); \ + } while (0) +#endif /* __vax__ */ + +#ifdef _TMS320C6X +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do \ + { \ + UDItype __ll; \ + __asm__ ("addu .l1 %1, %2, %0" \ + : "=a" (__ll) : "a" (al), "a" (bl)); \ + (sl) = (USItype)__ll; \ + (sh) = ((USItype)(__ll >> 32)) + (ah) + (bh); \ + } \ + while (0) + +#ifdef _TMS320C6400_PLUS +#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UDItype __x = (UDItype) (USItype) (u) * (USItype) (v); \ + (w1) = (USItype) (__x >> 32); \ + (w0) = (USItype) (__x); \ + } while (0) +#endif /* _TMS320C6400_PLUS */ + +#define count_leading_zeros(count, x) ((count) = __builtin_clz (x)) +#ifdef _TMS320C6400 +#define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x)) +#endif +#define UMUL_TIME 4 +#define UDIV_TIME 40 +#endif /* _TMS320C6X */ + +#if defined (__xtensa__) && W_TYPE_SIZE == 32 +/* This code is not Xtensa-configuration-specific, so rely on the compiler + to expand builtin functions depending on what configuration features + are available. This avoids library calls when the operation can be + performed in-line. */ +#define umul_ppmm(w1, w0, u, v) \ + do { \ + DWunion __w; \ + __w.ll = __builtin_umulsidi3 (u, v); \ + w1 = __w.s.high; \ + w0 = __w.s.low; \ + } while (0) +#define __umulsidi3(u, v) __builtin_umulsidi3 (u, v) +#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) +#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) +#endif /* __xtensa__ */ + +#if defined xstormy16 +extern UHItype __stormy16_count_leading_zeros (UHItype); +#define count_leading_zeros(count, x) \ + do \ + { \ + UHItype size; \ + \ + /* We assume that W_TYPE_SIZE is a multiple of 16... */ \ + for ((count) = 0, size = W_TYPE_SIZE; size; size -= 16) \ + { \ + UHItype c; \ + \ + c = __clzhi2 ((x) >> (size - 16)); \ + (count) += c; \ + if (c != 16) \ + break; \ + } \ + } \ + while (0) +#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE +#endif + +#if defined (__z8000__) && W_TYPE_SIZE == 16 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "%0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "%1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union {long int __ll; \ + struct {unsigned int __h, __l;} __i; \ + } __xx; \ + unsigned int __m0 = (m0), __m1 = (m1); \ + __asm__ ("mult %S0,%H3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (__m0), \ + "rQR" (__m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + (xh) += ((((signed int) __m0 >> 15) & __m1) \ + + (((signed int) __m1 >> 15) & __m0)); \ + } while (0) +#endif /* __z8000__ */ + +#endif /* __GNUC__ */ + +/* If this machine has no inline assembler, use C macros. */ + +#if !defined (add_ssaaaa) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) + (bl); \ + (sh) = (ah) + (bh) + (__x < (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (sub_ddmmss) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - (__x > (al)); \ + (sl) = __x; \ + } while (0) +#endif + +/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of + smul_ppmm. */ +#if !defined (umul_ppmm) && defined (smul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UWtype __w1; \ + UWtype __xm0 = (u), __xm1 = (v); \ + smul_ppmm (__w1, w0, __xm0, __xm1); \ + (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \ + + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \ + } while (0) +#endif + +/* If we still don't have umul_ppmm, define it using plain C. */ +#if !defined (umul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UWtype __x0, __x1, __x2, __x3; \ + UHWtype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (UWtype) __ul * __vl; \ + __x1 = (UWtype) __ul * __vh; \ + __x2 = (UWtype) __uh * __vl; \ + __x3 = (UWtype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ + } while (0) +#endif + +#if !defined (__umulsidi3) +#define __umulsidi3(u, v) \ + ({DWunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) +#endif + +/* Define this unconditionally, so it can be used for debugging. */ +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + UWtype __d1, __d0, __q1, __q0; \ + UWtype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (UWtype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (UWtype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (UWtype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through + __udiv_w_sdiv (defined in libgcc or elsewhere). */ +#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) +#define udiv_qrnnd(q, r, nh, nl, d) \ + do { \ + USItype __r; \ + (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ + (r) = __r; \ + } while (0) +#endif + +/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ +#if !defined (udiv_qrnnd) +#define UDIV_NEEDS_NORMALIZATION 1 +#define udiv_qrnnd __udiv_qrnnd_c +#endif + +#if !defined (count_leading_zeros) +#define count_leading_zeros(count, x) \ + do { \ + UWtype __xr = (x); \ + UWtype __a; \ + \ + if (W_TYPE_SIZE <= 32) \ + { \ + __a = __xr < ((UWtype)1<<2*__BITS4) \ + ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ + : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ + } \ + else \ + { \ + for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ + if (((__xr >> __a) & 0xff) != 0) \ + break; \ + } \ + \ + (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ + } while (0) +#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE +#endif + +#if !defined (count_trailing_zeros) +/* Define count_trailing_zeros using count_leading_zeros. The latter might be + defined in asm, but if it is not, the C version above is good enough. */ +#define count_trailing_zeros(count, x) \ + do { \ + UWtype __ctz_x = (x); \ + UWtype __ctz_c; \ + count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ + (count) = W_TYPE_SIZE - 1 - __ctz_c; \ + } while (0) +#endif + +#ifndef UDIV_NEEDS_NORMALIZATION +#define UDIV_NEEDS_NORMALIZATION 0 +#endif diff --git a/libgcc/memcmp.c b/libgcc/memcmp.c new file mode 100644 index 0000000..2348afe --- /dev/null +++ b/libgcc/memcmp.c @@ -0,0 +1,16 @@ +/* Public domain. */ +#include <stddef.h> + +int +memcmp (const void *str1, const void *str2, size_t count) +{ + const unsigned char *s1 = str1; + const unsigned char *s2 = str2; + + while (count-- > 0) + { + if (*s1++ != *s2++) + return s1[-1] < s2[-1] ? -1 : 1; + } + return 0; +} diff --git a/libgcc/memcpy.c b/libgcc/memcpy.c new file mode 100644 index 0000000..58b1e40 --- /dev/null +++ b/libgcc/memcpy.c @@ -0,0 +1,12 @@ +/* Public domain. */ +#include <stddef.h> + +void * +memcpy (void *dest, const void *src, size_t len) +{ + char *d = dest; + const char *s = src; + while (len--) + *d++ = *s++; + return dest; +} diff --git a/libgcc/memmove.c b/libgcc/memmove.c new file mode 100644 index 0000000..13b340a --- /dev/null +++ b/libgcc/memmove.c @@ -0,0 +1,20 @@ +/* Public domain. */ +#include <stddef.h> + +void * +memmove (void *dest, const void *src, size_t len) +{ + char *d = dest; + const char *s = src; + if (d < s) + while (len--) + *d++ = *s++; + else + { + char *lasts = s + (len-1); + char *lastd = d + (len-1); + while (len--) + *lastd-- = *lasts--; + } + return dest; +} diff --git a/libgcc/memset.c b/libgcc/memset.c new file mode 100644 index 0000000..3e7025e --- /dev/null +++ b/libgcc/memset.c @@ -0,0 +1,11 @@ +/* Public domain. */ +#include <stddef.h> + +void * +memset (void *dest, int val, size_t len) +{ + unsigned char *ptr = dest; + while (len-- > 0) + *ptr++ = val; + return dest; +} diff --git a/libgcc/siditi-object.mk b/libgcc/siditi-object.mk index 69df833..77699cb 100644 --- a/libgcc/siditi-object.mk +++ b/libgcc/siditi-object.mk @@ -11,12 +11,12 @@ iter-labels := $(wordlist 2,$(words $(iter-labels)),$(iter-labels)) $o-size := $(firstword $(iter-sizes)) iter-sizes := $(wordlist 2,$(words $(iter-sizes)),$(iter-sizes)) -$o$(objext): %$(objext): $(gcc_srcdir)/libgcc2.c - $(gcc_compile) -DL$($*-label) -c $(gcc_srcdir)/libgcc2.c $(vis_hide) \ +$o$(objext): %$(objext): $(srcdir)/libgcc2.c + $(gcc_compile) -DL$($*-label) -c $< $(vis_hide) \ -DLIBGCC2_UNITS_PER_WORD=$($*-size) ifeq ($(enable_shared),yes) -$(o)_s$(objext): %_s$(objext): $(gcc_srcdir)/libgcc2.c - $(gcc_s_compile) -DL$($*-label) -c $(gcc_srcdir)/libgcc2.c \ +$(o)_s$(objext): %_s$(objext): $(srcdir)/libgcc2.c + $(gcc_s_compile) -DL$($*-label) -c $< \ -DLIBGCC2_UNITS_PER_WORD=$($*-size) endif diff --git a/libgcc/udivmod.c b/libgcc/udivmod.c new file mode 100644 index 0000000..dc70de6 --- /dev/null +++ b/libgcc/udivmod.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +long udivmodsi4 (); + +long +__udivsi3 (long a, long b) +{ + return udivmodsi4 (a, b, 0); +} + +long +__umodsi3 (long a, long b) +{ + return udivmodsi4 (a, b, 1); +} + diff --git a/libgcc/udivmodsi4.c b/libgcc/udivmodsi4.c new file mode 100644 index 0000000..39c030f --- /dev/null +++ b/libgcc/udivmodsi4.c @@ -0,0 +1,47 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +unsigned long +udivmodsi4(unsigned long num, unsigned long den, int modwanted) +{ + unsigned long bit = 1; + unsigned long res = 0; + + while (den < num && bit && !(den & (1L<<31))) + { + den <<=1; + bit <<=1; + } + while (bit) + { + if (num >= den) + { + num -= den; + res |= bit; + } + bit >>=1; + den >>=1; + } + if (modwanted) return num; + return res; +} |