1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00
1997-08-24 12:24  Ulrich Drepper  <drepper@cygnus.com>

	* configure.in (INSTALL): Quote `$'.

	* libc.map: Add __xpg_basename.

	* csu/Makefile (initfini.s): Disable optimization.

	* elf/dl-deps.c: Implement handling of DL_FILTER.

	* elf/dl-load.c (_dl_init_paths): Add error check.

	* intl/finddomain.c (_nl_find_domain): Correct comment.
	* intl/localealias.c: Include <bits/libc-lock.h> not <libc-lock.h>.

	* libio/stdio.h: Make {,v}snprintf available if __USE_BSD.
	Change extern inline functions to work correctly in C++.

	* locale/iso-4217.def: Update for more recent ISO 4217 version.

	* locale/loadlocale.c (_nl_load_locale): Add cast.

	* manual/message.texi: Finish gettext section.

	* posix/getopt_init.c: Don't use relative #include path.
	(__getopt_clean_environment): Change function to take pointer to
	environment as argument.  Optimize generation of test string a bit.
	* sysdeps/unix/sysv/linux/init-first.c: Call __getopt_clean_environment
	with additional argument.

	* poisx/glob.c: Add prototype for next_brace_sub.

	* sysdeps/generic/dl-sysdep.c: Recognize AT_BASE value on auxiliary
	vector.

	* sysdeps/i386/dl-machine.h (elf_machine_load_address): Rewrite
	to not generate relocation entry.  Suggested by Richard Henderson.
	(ELF_MACHINE_BEFORE_RTLD_RELOC): Removed.
	(elf_machine_runtime_setup): Add .aligns.

	* sysdeps/i386/fpu/fraiseexcpt.c: Add volatile to asms.

	* sysdeps/i386/fpu/bits/mathinline.h: Partially undo change of
	1997-08-14 03:14.  gcc 2.7.2* is really broken in some aspects.

	* sysdeps/standalone/i386/i386.h: Clean up asm statements a bit.
	* sysdeps/standalone/i960/i960ca.h: Likewise.

1997-08-22 19:04  Richard Henderson  <rth@cygnus.com>

	* elf/rtld.c (_dl_start): Init _dl_rtld_map.l_opencount due to
	undocumented test addition in _dl_map_object.

	Support ET_EXEC versions of ld.so, for debugging at least:

	* elf/dl-load.c (_dl_map_object): Add_name_to_object could get
	called despite the DT_SONAME != NULL test, segfaulting.  Simplify
	the code here as well.
	* elf/dl-lookup.c (do_lookup): Skip objects with no symtab.
	(_dl_setup_hash): Likewise for hash tables.
	* elf/dl-version.c (_dl_check_map_versions): Likewise for strtabs.
	* elf/rtld.c (_dl_start): Likewise for rpath.
	(_dl_rtld_libname2): New variable.
	(dl_main): Use it to add an soname for ourselves when we don't have
	one of our own.  Base it on the target's .interp.
	(dl_main): Again, skip printing of objects that don't have strtabs.

	Sparc 32 merge:

	* elf/dl-runtime.c (ELF_FIXUP_RETURN_VALUE): Provide default value.
	(fixup): Simplify code.  Use ELF_FIXUP_RETURN_VALUE.
	(profile_fixup): Likewise, though this still needs fixing for
	Sparc32 and PPC.
	* sysdeps/powerpc/dl-machine.h: Transmute ELF_FIXUP_RETURNS_ADDRESS
	to ELF_FIXUP_RETURN_VALUE.

	* sysdeps/sparc/sparc32/dl-machine.h: Implement lazy relocation.
	Fix up _dl_start_user to handle _dl_skip_args properly.
	Use _dl_hwcap to determine if "flush" is available/needed.

	* sysdeps/sparc/configure.in: Remove.  It doesn't actually do
	anything anymore, and what it did do is done somewhere else.
	* sysdeps/sparc/configure: Likewise.

	* sysdeps/sparc/fpu/bits/mathdef.h (FP_ILOGB0, FP_ILOGBNAN): New.

	* sysdeps/sparc/fpu/fraiseexcpt.c: Rearrange for smaller code.

	* sysdeps/sparc/sparc32/Makefile: Fix sparc->sparc/sparc32 bits
	in divrem expansions.

	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h (END, LOC): New
	definitions for assembly syntax differences.

	* sysdeps/sparc/sparc32/__longjmp.S: %g6,%g7 are reserved to the
	"system".  Use %g2,%g3 instead.  Use new local label macro.
	* sysdeps/sparc/sparc32/add_n.S: Use <sysdep.h> and ENTRY, END,
	and LOC for proper assembly headers/footers.
	* sysdeps/sparc/sparc32/addmul_1.S: Likewise.
	* sysdeps/sparc/sparc32/alloca.S: Likewise.
	* sysdeps/sparc/sparc32/dotmul.S: Likewise.
	* sysdeps/sparc/sparc32/lshift.S: Likewise.
	* sysdeps/sparc/sparc32/mul_1.S: Likewise.
	* sysdeps/sparc/sparc32/rshift.S: Likewise.
	* sysdeps/sparc/sparc32/sparcv8/addmul_1.S: Likewise.
	* sysdeps/sparc/sparc32/sparcv8/mul_1.S: Likewise.
	* sysdeps/sparc/sparc32/sparcv8/submul_1.S: Likewise.
	* sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S: Likewise.
	* sysdeps/sparc/sparc32/sub_n.S: Likewise.
	* sysdeps/sparc/sparc32/submul_1.S: Likewise.
	* sysdeps/sparc/sparc32/udiv_qrnnd.S: Likewise.
	* sysdeps/sparc/sparc32/umul.S: Likewise.
	* sysdeps/sparc/sparc32/divrem.m4: Likewise.
	* sysdeps/sparc/sparc32/rem.S: Regenerate.
	* sysdeps/sparc/sparc32/sdiv.S: Regenerate.
	* sysdeps/sparc/sparc32/udiv.S: Regenerate.
	* sysdeps/sparc/sparc32/urem.S: Regenerate.

	* sysdeps/sparc/sparc32/sparcv8/dotmul.S: New file.
	* sysdeps/sparc/sparc32/sparcv8/rem.S: New file.
	* sysdeps/sparc/sparc32/sparcv8/sdiv.S: New file.
	* sysdeps/sparc/sparc32/sparcv8/udiv.S: New file.
	* sysdeps/sparc/sparc32/sparcv8/umul.S: New file.
	* sysdeps/sparc/sparc32/sparcv8/urem.S: New file.

	* sysdeps/sparc/sparc32/bsd-_setjmp.S: Dike out.
	* sysdeps/sparc/sparc32/bsd-setjmp.S: Likewise.
	* sysdeps/sparc/sparc32/setjmp.S: Add _setjmp and setjmp entry points.

	* sysdeps/unix/sysv/linux/sparc/sparc32/__sigtrampoline.S:
	Clean up PIC code.

	* sysdeps/sparc/sparc32/elf/start.S: New file, slightly modified
	from the sparc64 version.
	* sysdeps/sparc/sparc32/elf/start.c: Removed.

	* sysdeps/unix/sysv/linux/sparc/sparc32/init-first.h: Rewrite in
	assembly based on the sparc64 version.

	* sysdeps/sparc/sparc32/fpu/bits/fenv.h: Duh.  Use proper syntax
	for manipulating %fsr.
	* sysdeps/sparc/sparc32/fpu/fpu_control.h: Make IEEE conformance
	be the default.

	* elf/elf.h (HWCAP_SPARC_*): New definitions.
	* elf/rtld.c (_dl_hwcap): New variable.
	* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Record AT_HWCAP.

	* sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c: New file.
	Attempt to get hold of the page size based on what we might have
	been told at startup time in _dl_pagesize.  This will be obsolete
	when I finish the kernel hooks for a proper sysconf(), stay tuned.

	Sparc 64 merge:

	* sysdeps/sparc/sparc64/dl-machine.h (ELF_FIXUP_RETURN_VALUE): New.
	Figure out the right thing to return based on the .plt format.

	* sysdeps/sparc/sparc64/fpu/fpu_control.h: Update comment.

	* sysdeps/unix/sysv/linux/sparc/sparc64/bits/types.h (__dev_t):
	Should have been 64-bits wide.

	* sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h: sll->sllx,
	optimize for branch delay slot usage.

1997-08-22  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* csu/Makefile ($(objpfx)crt%.o): Fix a missing *.so -> *.os
	change.

1997-08-20  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* math/libm-test.c (identities): Change epsilon.

	* sysdeps/i386/fpu/bits/mathinline.h: Correct arguments to fabs,
	fabsf, fabsl, __fabsl.

	* sysdeps/libm-i387/e_remainderl.S: Pop extra value from FPU stack.
	* sysdeps/libm-ieee754/s_csinhl.c: Include <fenv.h>.
This commit is contained in:
Ulrich Drepper
1997-08-24 10:55:18 +00:00
parent 40a55d2054
commit f41c80910d
80 changed files with 3162 additions and 2506 deletions

182
ChangeLog
View File

@ -1,3 +1,181 @@
1997-08-24 12:24 Ulrich Drepper <drepper@cygnus.com>
* configure.in (INSTALL): Quote `$'.
* libc.map: Add __xpg_basename.
* csu/Makefile (initfini.s): Disable optimization.
* elf/dl-deps.c: Implement handling of DL_FILTER.
* elf/dl-load.c (_dl_init_paths): Add error check.
* intl/finddomain.c (_nl_find_domain): Correct comment.
* intl/localealias.c: Include <bits/libc-lock.h> not <libc-lock.h>.
* libio/stdio.h: Make {,v}snprintf available if __USE_BSD.
Change extern inline functions to work correctly in C++.
* locale/iso-4217.def: Update for more recent ISO 4217 version.
* locale/loadlocale.c (_nl_load_locale): Add cast.
* manual/message.texi: Finish gettext section.
* posix/getopt_init.c: Don't use relative #include path.
(__getopt_clean_environment): Change function to take pointer to
environment as argument. Optimize generation of test string a bit.
* sysdeps/unix/sysv/linux/init-first.c: Call __getopt_clean_environment
with additional argument.
* poisx/glob.c: Add prototype for next_brace_sub.
* sysdeps/generic/dl-sysdep.c: Recognize AT_BASE value on auxiliary
vector.
* sysdeps/i386/dl-machine.h (elf_machine_load_address): Rewrite
to not generate relocation entry. Suggested by Richard Henderson.
(ELF_MACHINE_BEFORE_RTLD_RELOC): Removed.
(elf_machine_runtime_setup): Add .aligns.
* sysdeps/i386/fpu/fraiseexcpt.c: Add volatile to asms.
* sysdeps/i386/fpu/bits/mathinline.h: Partially undo change of
1997-08-14 03:14. gcc 2.7.2* is really broken in some aspects.
* sysdeps/standalone/i386/i386.h: Clean up asm statements a bit.
* sysdeps/standalone/i960/i960ca.h: Likewise.
1997-08-22 19:04 Richard Henderson <rth@cygnus.com>
* elf/rtld.c (_dl_start): Init _dl_rtld_map.l_opencount due to
undocumented test addition in _dl_map_object.
Support ET_EXEC versions of ld.so, for debugging at least:
* elf/dl-load.c (_dl_map_object): Add_name_to_object could get
called despite the DT_SONAME != NULL test, segfaulting. Simplify
the code here as well.
* elf/dl-lookup.c (do_lookup): Skip objects with no symtab.
(_dl_setup_hash): Likewise for hash tables.
* elf/dl-version.c (_dl_check_map_versions): Likewise for strtabs.
* elf/rtld.c (_dl_start): Likewise for rpath.
(_dl_rtld_libname2): New variable.
(dl_main): Use it to add an soname for ourselves when we don't have
one of our own. Base it on the target's .interp.
(dl_main): Again, skip printing of objects that don't have strtabs.
Sparc 32 merge:
* elf/dl-runtime.c (ELF_FIXUP_RETURN_VALUE): Provide default value.
(fixup): Simplify code. Use ELF_FIXUP_RETURN_VALUE.
(profile_fixup): Likewise, though this still needs fixing for
Sparc32 and PPC.
* sysdeps/powerpc/dl-machine.h: Transmute ELF_FIXUP_RETURNS_ADDRESS
to ELF_FIXUP_RETURN_VALUE.
* sysdeps/sparc/sparc32/dl-machine.h: Implement lazy relocation.
Fix up _dl_start_user to handle _dl_skip_args properly.
Use _dl_hwcap to determine if "flush" is available/needed.
* sysdeps/sparc/configure.in: Remove. It doesn't actually do
anything anymore, and what it did do is done somewhere else.
* sysdeps/sparc/configure: Likewise.
* sysdeps/sparc/fpu/bits/mathdef.h (FP_ILOGB0, FP_ILOGBNAN): New.
* sysdeps/sparc/fpu/fraiseexcpt.c: Rearrange for smaller code.
* sysdeps/sparc/sparc32/Makefile: Fix sparc->sparc/sparc32 bits
in divrem expansions.
* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h (END, LOC): New
definitions for assembly syntax differences.
* sysdeps/sparc/sparc32/__longjmp.S: %g6,%g7 are reserved to the
"system". Use %g2,%g3 instead. Use new local label macro.
* sysdeps/sparc/sparc32/add_n.S: Use <sysdep.h> and ENTRY, END,
and LOC for proper assembly headers/footers.
* sysdeps/sparc/sparc32/addmul_1.S: Likewise.
* sysdeps/sparc/sparc32/alloca.S: Likewise.
* sysdeps/sparc/sparc32/dotmul.S: Likewise.
* sysdeps/sparc/sparc32/lshift.S: Likewise.
* sysdeps/sparc/sparc32/mul_1.S: Likewise.
* sysdeps/sparc/sparc32/rshift.S: Likewise.
* sysdeps/sparc/sparc32/sparcv8/addmul_1.S: Likewise.
* sysdeps/sparc/sparc32/sparcv8/mul_1.S: Likewise.
* sysdeps/sparc/sparc32/sparcv8/submul_1.S: Likewise.
* sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S: Likewise.
* sysdeps/sparc/sparc32/sub_n.S: Likewise.
* sysdeps/sparc/sparc32/submul_1.S: Likewise.
* sysdeps/sparc/sparc32/udiv_qrnnd.S: Likewise.
* sysdeps/sparc/sparc32/umul.S: Likewise.
* sysdeps/sparc/sparc32/divrem.m4: Likewise.
* sysdeps/sparc/sparc32/rem.S: Regenerate.
* sysdeps/sparc/sparc32/sdiv.S: Regenerate.
* sysdeps/sparc/sparc32/udiv.S: Regenerate.
* sysdeps/sparc/sparc32/urem.S: Regenerate.
* sysdeps/sparc/sparc32/sparcv8/dotmul.S: New file.
* sysdeps/sparc/sparc32/sparcv8/rem.S: New file.
* sysdeps/sparc/sparc32/sparcv8/sdiv.S: New file.
* sysdeps/sparc/sparc32/sparcv8/udiv.S: New file.
* sysdeps/sparc/sparc32/sparcv8/umul.S: New file.
* sysdeps/sparc/sparc32/sparcv8/urem.S: New file.
* sysdeps/sparc/sparc32/bsd-_setjmp.S: Dike out.
* sysdeps/sparc/sparc32/bsd-setjmp.S: Likewise.
* sysdeps/sparc/sparc32/setjmp.S: Add _setjmp and setjmp entry points.
* sysdeps/unix/sysv/linux/sparc/sparc32/__sigtrampoline.S:
Clean up PIC code.
* sysdeps/sparc/sparc32/elf/start.S: New file, slightly modified
from the sparc64 version.
* sysdeps/sparc/sparc32/elf/start.c: Removed.
* sysdeps/unix/sysv/linux/sparc/sparc32/init-first.h: Rewrite in
assembly based on the sparc64 version.
* sysdeps/sparc/sparc32/fpu/bits/fenv.h: Duh. Use proper syntax
for manipulating %fsr.
* sysdeps/sparc/sparc32/fpu/fpu_control.h: Make IEEE conformance
be the default.
* elf/elf.h (HWCAP_SPARC_*): New definitions.
* elf/rtld.c (_dl_hwcap): New variable.
* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Record AT_HWCAP.
* sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c: New file.
Attempt to get hold of the page size based on what we might have
been told at startup time in _dl_pagesize. This will be obsolete
when I finish the kernel hooks for a proper sysconf(), stay tuned.
Sparc 64 merge:
* sysdeps/sparc/sparc64/dl-machine.h (ELF_FIXUP_RETURN_VALUE): New.
Figure out the right thing to return based on the .plt format.
* sysdeps/sparc/sparc64/fpu/fpu_control.h: Update comment.
* sysdeps/unix/sysv/linux/sparc/sparc64/bits/types.h (__dev_t):
Should have been 64-bits wide.
* sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h: sll->sllx,
optimize for branch delay slot usage.
1997-08-22 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* csu/Makefile ($(objpfx)crt%.o): Fix a missing *.so -> *.os
change.
1997-08-20 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* math/libm-test.c (identities): Change epsilon.
* sysdeps/i386/fpu/bits/mathinline.h: Correct arguments to fabs,
fabsf, fabsl, __fabsl.
1997-08-20 05:30 Ulrich Drepper <drepper@cygnus.com> 1997-08-20 05:30 Ulrich Drepper <drepper@cygnus.com>
* catgets/catgets.c (catclose): Use __munmap instead of munmap. * catgets/catgets.c (catclose): Use __munmap instead of munmap.
@ -120,10 +298,10 @@
* sysdeps/libm-i387/e_remainder.S: Pretty print. * sysdeps/libm-i387/e_remainder.S: Pretty print.
* sysdeps/libm-i387/e_remainderf.S: Likewise. * sysdeps/libm-i387/e_remainderf.S: Likewise.
* sysdeps/libm-i387/e_remainderl.S: Pop extra value for FPU stack. * sysdeps/libm-i387/e_remainderl.S: Pop extra value from FPU stack.
* sysdeps/libm-i387/s_cexp.S: Little optimization. * sysdeps/libm-i387/s_cexp.S: Little optimization.
* sysdeps/libm-i387/s_cexpl.S: Likewise. * sysdeps/libm-i387/s_cexpl.S: Likewise.
* sysdep/libm-ieee754/s_csinhl.c: Include <fenv.h>. * sysdeps/libm-ieee754/s_csinhl.c: Include <fenv.h>.
1997-08-18 15:21 Ulrich Drepper <drepper@cygnus.com> 1997-08-18 15:21 Ulrich Drepper <drepper@cygnus.com>

51
FAQ
View File

@ -565,7 +565,7 @@ by
in the above example specs file to make it work for other systems. in the above example specs file to make it work for other systems.
Version 2.7.2.2 does and future versions of GCC will automatically Version 2.7.2.3 does and future versions of GCC will automatically
provide the correct specs. provide the correct specs.
@ -595,13 +595,9 @@ GROUP ( libc.so.6 ld-linux.so.2 libc.a )
any other system I saw. This is a bug, isn't it?'' any other system I saw. This is a bug, isn't it?''
[A18] {UD} No, this is no bug. This version of the GNU libc already [A18] {UD} No, this is no bug. This version of the GNU libc already
follows the to-be-released POSIX.1g standard. In this standard follows the Single Unix specifications (and I think the POSIX.1g
the type `size_t' is used for all parameters which describe a size. draft which adopted the solution). The type for parameter describing
So better change now. a size is now `socklen_t', a new type.
This change is critical for system which have
sizeof (int) != sizeof (size_t)
like the Alpha.
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@ -617,28 +613,9 @@ invalid. I.e., an emulated FPU is for the libc as good as a real one.
[Q20] ``How can I compile gcc 2.7.2.1 from the gcc source code using [Q20] ``How can I compile gcc 2.7.2.1 from the gcc source code using
glibc 2.x? glibc 2.x?
[A20] {AJ} There's only support for glibc 2.0 in gcc 2.7.2.2 or later. [A20] {AJ} There's only correct support for glibc 2.0.x in gcc 2.7.2.3
or later. You should get at least gcc 2.7.2.3. All previous versions
gcc 2.7.2.2 has also a nasty bug. It installs its own version of had problems with glibc support.
assert.h into /usr/<machine>/include that is not compatible with
glibc. Please remove this file - otherwise you get lots of problems
with configure.
For 2.7.2.2 you should also use the following patch and configure for
e.g. i486-linux.
-----------------------------------------------------------------------
--- configure Tue Feb 11 15:57:17 1997
+++ configure Wed Feb 12 23:09:29 1997
@@ -1021,7 +1021,7 @@
gnu_ld=yes
# GNU libc version 2 does not supply these;
# we want them from GCC.
- extra_parts="crtbegin.o crtend.o"
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
;;
i[3456]86-go32-msdos | i[3456]86-*-go32)
cpu_type=i386
-----------------------------------------------------------------------
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@ -698,13 +675,13 @@ very beginning and if it is not usable `configure' will bark.
[Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS [Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
works great. But the glibc NIS+ doesn't seem to work.'' works great. But the glibc NIS+ doesn't seem to work.''
[A24] The glibc NIS+ implementation uses a /var/nis/NIS_COLD_START [A24] The glibc NIS+ implementation uses a /var/nis/NIS_COLD_START
file for storing information about the NIS+ server and their file for storing information about the NIS+ server and their public
public keys, because the nis.conf file do not contain all keys, because the nis.conf file do not contain all necessary
necessary information. You have to copy a NIS_COLD_START file information. You have to copy a NIS_COLD_START file from a Solaris
from a Solaris client (the NIS_COLD_START file is byte order client (the NIS_COLD_START file is byte order independend) or generate
independend) or generate it new with nisinit from the nis-tools it new with nisinit from the nis-tools (look at
(look at http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html). http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html).
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

11
config.sub vendored
View File

@ -155,6 +155,7 @@ case $basic_machine in
| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \ | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \ | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
| mipstx39 | mipstx39el \
| sparc | sparclet | sparclite | sparc64) | sparc | sparclet | sparclite | sparc64)
basic_machine=$basic_machine-unknown basic_machine=$basic_machine-unknown
;; ;;
@ -179,7 +180,9 @@ case $basic_machine in
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \ | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | mips64-* | mipsel-* \ | sparc64-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* | f301-*) | mips64el-* | mips64orion-* | mips64orionel-* \
| mipstx39-* | mipstx39el-* \
| f301-*)
;; ;;
# Recognize the various machine names and aliases which stand # Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS. # for a CPU type and a company and sometimes even an OS.
@ -568,6 +571,12 @@ case $basic_machine in
basic_machine=i386-sequent basic_machine=i386-sequent
os=-dynix os=-dynix
;; ;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
tower | tower-32) tower | tower-32)
basic_machine=m68k-ncr basic_machine=m68k-ncr
;; ;;

2
configure vendored
View File

@ -1091,7 +1091,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
if test "$INSTALL" = "${srcdir}/install-sh -c"; then if test "$INSTALL" = "${srcdir}/install-sh -c"; then
# The makefiles need to use a different form to find it in $srcdir. # The makefiles need to use a different form to find it in $srcdir.
INSTALL='$(..)./install-sh -c' INSTALL='\$(..)./install-sh -c'
fi fi
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
echo "configure:1098: checking whether ln -s works" >&5 echo "configure:1098: checking whether ln -s works" >&5

View File

@ -371,7 +371,7 @@ AC_MSG_RESULT(sysdeps/generic sysdeps/stub)
AC_PROG_INSTALL AC_PROG_INSTALL
if test "$INSTALL" = "${srcdir}/install-sh -c"; then if test "$INSTALL" = "${srcdir}/install-sh -c"; then
# The makefiles need to use a different form to find it in $srcdir. # The makefiles need to use a different form to find it in $srcdir.
INSTALL='$(..)./install-sh -c' INSTALL='\$(..)./install-sh -c'
fi fi
AC_PROG_LN_S AC_PROG_LN_S
AC_CHECK_PROGS(MSGFMT, msgfmt gmsgfmt, :) AC_CHECK_PROGS(MSGFMT, msgfmt gmsgfmt, :)

View File

@ -59,10 +59,10 @@ omit-deps += $(crtstuff)
# Special rules for the building of crti.o and crtn.o # Special rules for the building of crti.o and crtn.o
$(objpfx)crt%.o: $(objpfx)crt%.S $(objpfx)defs.h $(objpfx)crt%.o: $(objpfx)crt%.S $(objpfx)defs.h
$(compile.S) -g0 $(ASFLAGS-.so) -o $@ $(compile.S) -g0 $(ASFLAGS-.os) -o $@
$(objpfx)initfini.s: initfini.c $(objpfx)initfini.s: initfini.c
$(compile.c) -g0 -S -fPIC -finhibit-size-directive \ $(compile.c) -O0 -g0 -S -fPIC -finhibit-size-directive \
$(no-exceptions) -o $@ $(no-exceptions) -o $@
# We only have one kind of startup code files. Static binaries and # We only have one kind of startup code files. Static binaries and

View File

@ -28,6 +28,10 @@
is signaled by the AUXTAG entry in l_info. */ is signaled by the AUXTAG entry in l_info. */
#define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \ #define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
+ DT_EXTRATAGIDX (DT_AUXILIARY)) + DT_EXTRATAGIDX (DT_AUXILIARY))
/* Whether an shared object references one or more auxiliary objects
is signaled by the AUXTAG entry in l_info. */
#define FILTERTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
+ DT_EXTRATAGIDX (DT_FILTER))
/* When loading auxiliary objects we must ignore errors. It's ok if /* When loading auxiliary objects we must ignore errors. It's ok if
@ -138,7 +142,7 @@ _dl_map_object_deps (struct link_map *map,
{ {
struct link_map *l = runp->map; struct link_map *l = runp->map;
if (l->l_info[AUXTAG] || l->l_info[DT_NEEDED]) if (l->l_info[AUXTAG] || l->l_info[FILTERTAG] || l->l_info[DT_NEEDED])
{ {
const char *strtab = ((void *) l->l_addr const char *strtab = ((void *) l->l_addr
+ l->l_info[DT_STRTAB]->d_un.d_ptr); + l->l_info[DT_STRTAB]->d_un.d_ptr);
@ -190,119 +194,87 @@ _dl_map_object_deps (struct link_map *map,
dep->l_reserved = 1; dep->l_reserved = 1;
} }
} }
else if (d->d_tag == DT_AUXILIARY) else if (d->d_tag == DT_AUXILIARY || d->d_tag == DT_FILTER)
{ {
char *errstring; char *errstring;
const char *objname; const char *objname;
struct list *newp;
/* Store the tag in the argument structure. */ if (d->d_tag == DT_AUXILIARY)
args.d = d;
if (_dl_catch_error (&errstring, &objname, openaux, &args))
{ {
/* We are not interested in the error message. */ /* Store the tag in the argument structure. */
assert (errstring != NULL); args.d = d;
free (errstring);
/* We must be prepared that the addressed shared
object is not available. */
if (_dl_catch_error (&errstring, &objname, openaux, &args))
{
/* We are not interested in the error message. */
assert (errstring != NULL);
free (errstring);
/* Simply ignore this error and continue the work. */
continue;
}
} }
else else
/* For filter objects the dependency must be available. */
args.aux = _dl_map_object (l, strtab + d->d_un.d_val,
(l->l_type == lt_executable
? lt_library : l->l_type),
trace_mode);
/* The auxiliary object is actually available.
Incorporate the map in all the lists. */
/* Allocate new entry. This always has to be done. */
newp = alloca (sizeof (struct list));
/* Copy the content of the current entry over. */
memcpy (newp, orig, sizeof (*newp));
/* Initialize new entry. */
orig->done = 0;
orig->map = args.aux;
orig->dup = newp;
/* We must handle two situations here: the map is new,
so we must add it in all three lists. If the map
is already known, we have two further possibilities:
- if the object is before the current map in the
search list, we do nothing. It is already found
early
- if the object is after the current one, we must
move it just before the current map to make sure
the symbols are found early enough
*/
if (args.aux->l_reserved)
{ {
/* The auxiliary object is actually available. /* The object is already somewhere in the list.
Incorporate the map in all the lists. */ Locate it first. */
struct list *late;
/* Allocate new entry. This always has to be done. */ /* This object is already in the search list we
struct list *newp = alloca (sizeof (struct list)); are building. Don't add a duplicate pointer.
Release the reference just added by
_dl_map_object. */
--args.aux->l_opencount;
/* Copy the content of the current entry over. */ for (late = orig; late->unique; late = late->unique)
memcpy (newp, orig, sizeof (*newp)); if (late->unique->map == args.aux)
break;
/* Initialize new entry. */ if (late->unique)
orig->done = 0;
orig->map = args.aux;
orig->dup = newp;
/* We must handle two situations here: the map is new,
so we must add it in all three lists. If the map
is already known, we have two further possibilities:
- if the object is before the current map in the
search list, we do nothing. It is already found
early
- if the object is after the current one, we must
move it just before the current map to make sure
the symbols are found early enough
*/
if (args.aux->l_reserved)
{ {
/* The object is already somewhere in the /* The object is somewhere behind the current
list. Locate it first. */ position in the search path. We have to
struct list *late; move it to this earlier position. */
/* This object is already in the search list
we are building. Don't add a duplicate
pointer. Release the reference just added
by _dl_map_object. */
--args.aux->l_opencount;
for (late = orig; late->unique; late = late->unique)
if (late->unique->map == args.aux)
break;
if (late->unique)
{
/* The object is somewhere behind the current
position in the search path. We have to
move it to this earlier position. */
orig->unique = newp;
/* Now remove the later entry from the unique
list. */
late->unique = late->unique->unique;
/* We must move the earlier in the chain. */
if (args.aux->l_prev)
args.aux->l_prev->l_next = args.aux->l_next;
if (args.aux->l_next)
args.aux->l_next->l_prev = args.aux->l_prev;
args.aux->l_prev = newp->map->l_prev;
newp->map->l_prev = args.aux;
if (args.aux->l_prev != NULL)
args.aux->l_prev->l_next = args.aux;
args.aux->l_next = newp->map;
}
else
{
/* The object must be somewhere earlier in
the list. That's good, we only have to
insert an entry for the duplicate list. */
orig->unique = NULL; /* Never used. */
/* Now we have a problem. The element pointing
to ORIG in the unique list must point to
NEWP now. This is the only place where we
need this backreference and this situation
is really not that frequent. So we don't
use a double-linked list but instead search
for the preceding element. */
late = head;
while (late->unique != orig)
late = late->unique;
late->unique = newp;
}
}
else
{
/* This is easy. We just add the symbol right
here. */
orig->unique = newp; orig->unique = newp;
++nlist;
/* Set the mark bit that says it's already in
the list. */
args.aux->l_reserved = 1;
/* The only problem is that in the double linked /* Now remove the later entry from the unique list. */
list of all objects we don't have this new late->unique = late->unique->unique;
object at the correct place. Correct this
here. */ /* We must move the earlier in the chain. */
if (args.aux->l_prev) if (args.aux->l_prev)
args.aux->l_prev->l_next = args.aux->l_next; args.aux->l_prev->l_next = args.aux->l_next;
if (args.aux->l_next) if (args.aux->l_next)
@ -314,19 +286,60 @@ _dl_map_object_deps (struct link_map *map,
args.aux->l_prev->l_next = args.aux; args.aux->l_prev->l_next = args.aux;
args.aux->l_next = newp->map; args.aux->l_next = newp->map;
} }
else
{
/* The object must be somewhere earlier in the
list. That's good, we only have to insert
an entry for the duplicate list. */
orig->unique = NULL; /* Never used. */
/* Move the tail pointers if necessary. */ /* Now we have a problem. The element
if (orig == utail) pointing to ORIG in the unique list must
utail = newp; point to NEWP now. This is the only place
if (orig == dtail) where we need this backreference and this
dtail = newp; situation is really not that frequent. So
we don't use a double-linked list but
/* Move on the insert point. */ instead search for the preceding element. */
orig = newp; late = head;
while (late->unique != orig)
/* We always add an entry to the duplicate list. */ late = late->unique;
++nduplist; late->unique = newp;
}
} }
else
{
/* This is easy. We just add the symbol right here. */
orig->unique = newp;
++nlist;
/* Set the mark bit that says it's already in the list. */
args.aux->l_reserved = 1;
/* The only problem is that in the double linked
list of all objects we don't have this new
object at the correct place. Correct this here. */
if (args.aux->l_prev)
args.aux->l_prev->l_next = args.aux->l_next;
if (args.aux->l_next)
args.aux->l_next->l_prev = args.aux->l_prev;
args.aux->l_prev = newp->map->l_prev;
newp->map->l_prev = args.aux;
if (args.aux->l_prev != NULL)
args.aux->l_prev->l_next = args.aux;
args.aux->l_next = newp->map;
}
/* Move the tail pointers if necessary. */
if (orig == utail)
utail = newp;
if (orig == dtail)
dtail = newp;
/* Move on the insert point. */
orig = newp;
/* We always add an entry to the duplicate list. */
++nduplist;
} }
} }
else else

View File

@ -406,6 +406,9 @@ _dl_init_paths (void)
{ {
fake_path_list = (struct r_search_path_elem **) fake_path_list = (struct r_search_path_elem **)
malloc ((nllp + 1) * sizeof (struct r_search_path_elem *)); malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
if (fake_path_list == NULL)
_dl_signal_error (ENOMEM, NULL,
"cannot create cache for search path");
(void) fillin_rpath (local_strdup (llp), fake_path_list, ":;", (void) fillin_rpath (local_strdup (llp), fake_path_list, ":;",
__libc_enable_secure ? trusted_dirs : NULL); __libc_enable_secure ? trusted_dirs : NULL);
@ -901,23 +904,33 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
/* Look for this name among those already loaded. */ /* Look for this name among those already loaded. */
for (l = _dl_loaded; l; l = l->l_next) for (l = _dl_loaded; l; l = l->l_next)
if (l->l_opencount > 0 && _dl_name_match_p (name, l) || {
/* If the requested name matches the soname of a loaded object, /* If the requested name matches the soname of a loaded object,
use that object. */ use that object. Elide this check for names that have not
(l->l_info[DT_SONAME] && yet been opened. */
! strcmp (name, (const char *) (l->l_addr + if (l->l_opencount <= 0)
l->l_info[DT_STRTAB]->d_un.d_ptr + continue;
l->l_info[DT_SONAME]->d_un.d_val)))) if (!_dl_name_match_p (name, l))
{ {
/* The object is already loaded. const char *soname;
Just bump its reference count and return it. */
const char *soname = (const char *) (l->l_addr + if (l->l_info[DT_SONAME] == NULL)
l->l_info[DT_STRTAB]->d_un.d_ptr + continue;
l->l_info[DT_SONAME]->d_un.d_val);
add_name_to_object (l, local_strdup (soname)); soname = (const char *) (l->l_addr
++l->l_opencount; + l->l_info[DT_STRTAB]->d_un.d_ptr
return l; + l->l_info[DT_SONAME]->d_un.d_val);
} if (strcmp (name, soname) != 0)
continue;
/* We have a match on a new name -- cache it. */
add_name_to_object (l, local_strdup (soname));
}
/* We have a match -- bump the reference count and return it. */
++l->l_opencount;
return l;
}
if (strchr (name, '/') == NULL) if (strchr (name, '/') == NULL)
{ {

View File

@ -93,6 +93,10 @@ do_lookup (const char *undef_name, unsigned long int hash,
map->l_type == lt_executable) map->l_type == lt_executable)
continue; continue;
/* Skip objects without symbol tables. */
if (map->l_info[DT_SYMTAB] == NULL)
continue;
symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr); symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr); strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
if (map->l_nversions > 0 && map->l_info[VERSTAG (DT_VERSYM)] != NULL) if (map->l_nversions > 0 && map->l_info[VERSTAG (DT_VERSYM)] != NULL)
@ -364,8 +368,13 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
void void
_dl_setup_hash (struct link_map *map) _dl_setup_hash (struct link_map *map)
{ {
ElfW(Symndx) *hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr); ElfW(Symndx) *hash;
ElfW(Symndx) nchain; ElfW(Symndx) nchain;
if (!map->l_info[DT_HASH])
return;
hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
map->l_nbuckets = *hash++; map->l_nbuckets = *hash++;
nchain = *hash++; nchain = *hash++;
map->l_buckets = hash; map->l_buckets = hash;

View File

@ -87,6 +87,10 @@ _dl_object_relocation_scope (struct link_map *l)
# define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym)) # define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
#endif #endif
#ifndef ELF_FIXUP_RETURN_VALUE
#define ELF_FIXUP_RETURN_VALUE(map, result) (result)
#endif
/* We need to define the function as a local symbol so that the reference /* We need to define the function as a local symbol so that the reference
in the trampoline code will be a local PC-relative call. Tell the in the trampoline code will be a local PC-relative call. Tell the
compiler not to worry that the function appears not to be called. */ compiler not to worry that the function appears not to be called. */
@ -120,6 +124,7 @@ fixup (
const PLTREL *const reloc const PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr + = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
reloc_offset); reloc_offset);
ElfW(Addr) *const rel_addr = (ElfW(Addr) *)(l->l_addr + reloc->r_offset);
/* Set up the scope to find symbols referenced by this object. */ /* Set up the scope to find symbols referenced by this object. */
struct link_map **scope = _dl_object_relocation_scope (l); struct link_map **scope = _dl_object_relocation_scope (l);
@ -144,21 +149,17 @@ fixup (
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)], elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
&l->l_versions[ndx], &l->l_versions[ndx],
(void *) (l->l_addr + reloc->r_offset)); (void *) rel_addr);
} }
else else
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)], elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
NULL, (void *) (l->l_addr + reloc->r_offset)); NULL, (void *) rel_addr);
} }
*_dl_global_scope_end = NULL; *_dl_global_scope_end = NULL;
/* Return the address that was written by the relocation. */ /* Return the address that was written by the relocation. */
#ifdef ELF_FIXUP_RETURNS_ADDRESS return ELF_FIXUP_RETURN_VALUE(l, *rel_addr);
return (ElfW(Addr))(l->l_addr + reloc->r_offset);
#else
return *(ElfW(Addr) *) (l->l_addr + reloc->r_offset);
#endif
} }
@ -219,17 +220,10 @@ profile_fixup (
} }
*_dl_global_scope_end = NULL; *_dl_global_scope_end = NULL;
(*mcount_fct) (retaddr, result);
/* Return the address that was written by the relocation. */ /* Return the address that was written by the relocation. */
#ifdef ELF_FIXUP_RETURNS_ADDRESS return ELF_FIXUP_RETURN_VALUE(l, result);
(*mcount_fct) (retaddr, result);
return &result; /* XXX This cannot work. What to do??? --drepper */
#else
(*mcount_fct) (retaddr, result);
return result;
#endif
} }
#endif #endif

View File

@ -155,16 +155,23 @@ int
_dl_check_map_versions (struct link_map *map, int verbose) _dl_check_map_versions (struct link_map *map, int verbose)
{ {
int result = 0; int result = 0;
const char *strtab = (const char *) (map->l_addr const char *strtab;
+ map->l_info[DT_STRTAB]->d_un.d_ptr);
/* Pointer to section with needed versions. */ /* Pointer to section with needed versions. */
ElfW(Dyn) *dyn = map->l_info[VERSTAG (DT_VERNEED)]; ElfW(Dyn) *dyn;
/* Pointer to dynamic section with definitions. */ /* Pointer to dynamic section with definitions. */
ElfW(Dyn) *def = map->l_info[VERSTAG (DT_VERDEF)]; ElfW(Dyn) *def;
/* We need to find out which is the highest version index used /* We need to find out which is the highest version index used
in a dependecy. */ in a dependecy. */
unsigned int ndx_high = 0; unsigned int ndx_high = 0;
/* If we don't have a string table, we must be ok. */
if (map->l_info[DT_STRTAB] == NULL)
return 0;
strtab = (const char *) (map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
dyn = map->l_info[VERSTAG (DT_VERNEED)];
def = map->l_info[VERSTAG (DT_VERDEF)];
if (dyn != NULL) if (dyn != NULL)
{ {
/* This file requires special versions from its dependencies. */ /* This file requires special versions from its dependencies. */

View File

@ -783,6 +783,13 @@ typedef struct
#define DT_SPARC_PLTFMT 0x70000001 /* .plt format version/type */ #define DT_SPARC_PLTFMT 0x70000001 /* .plt format version/type */
#define DT_SPARC_NUM 2 #define DT_SPARC_NUM 2
/* Bits present in AT_HWCAP, primarily for Sparc32. */
#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */
#define HWCAP_SPARC_STBAR 2
#define HWCAP_SPARC_SWAP 4
#define HWCAP_SPARC_MULDIV 8
/* MIPS R3000 specific definitions. */ /* MIPS R3000 specific definitions. */
/* Legal values for e_flags field of Elf32_Ehdr. */ /* Legal values for e_flags field of Elf32_Ehdr. */

View File

@ -53,13 +53,13 @@ static void print_unresolved (int errcode, const char *objname,
static void print_missing_version (int errcode, const char *objname, static void print_missing_version (int errcode, const char *objname,
const char *errsting); const char *errsting);
int _dl_argc; int _dl_argc;
char **_dl_argv; char **_dl_argv;
const char *_dl_rpath; const char *_dl_rpath;
int _dl_verbose; int _dl_verbose;
const char *_dl_platform; const char *_dl_platform;
size_t _dl_platformlen; size_t _dl_platformlen;
unsigned long _dl_hwcap;
struct r_search_path *_dl_search_paths; struct r_search_path *_dl_search_paths;
const char *_dl_profile; const char *_dl_profile;
const char *_dl_profile_output; const char *_dl_profile_output;
@ -80,6 +80,7 @@ static void dl_main (const ElfW(Phdr) *phdr,
struct link_map _dl_rtld_map; struct link_map _dl_rtld_map;
struct libname_list _dl_rtld_libname; struct libname_list _dl_rtld_libname;
struct libname_list _dl_rtld_libname2;
#ifdef RTLD_START #ifdef RTLD_START
RTLD_START RTLD_START
@ -119,19 +120,22 @@ _dl_start (void *arg)
the operating system's program loader where to find the program the operating system's program loader where to find the program
header table in core. */ header table in core. */
/* Transfer data about ourselves to the permanent link_map structure. */ /* Transfer data about ourselves to the permanent link_map structure. */
_dl_rtld_map.l_addr = bootstrap_map.l_addr; _dl_rtld_map.l_addr = bootstrap_map.l_addr;
_dl_rtld_map.l_ld = bootstrap_map.l_ld; _dl_rtld_map.l_ld = bootstrap_map.l_ld;
_dl_rtld_map.l_opencount = 1;
memcpy (_dl_rtld_map.l_info, bootstrap_map.l_info, memcpy (_dl_rtld_map.l_info, bootstrap_map.l_info,
sizeof _dl_rtld_map.l_info); sizeof _dl_rtld_map.l_info);
_dl_setup_hash (&_dl_rtld_map); _dl_setup_hash (&_dl_rtld_map);
/* Cache the DT_RPATH stored in ld.so itself; this will be /* Cache the DT_RPATH stored in ld.so itself; this will be
the default search path. */ the default search path. */
_dl_rpath = (void *) (_dl_rtld_map.l_addr + if (_dl_rtld_map.l_info[DT_STRTAB] && _dl_rtld_map.l_info[DT_RPATH])
_dl_rtld_map.l_info[DT_STRTAB]->d_un.d_ptr + {
_dl_rtld_map.l_info[DT_RPATH]->d_un.d_val); _dl_rpath = (void *) (_dl_rtld_map.l_addr +
_dl_rtld_map.l_info[DT_STRTAB]->d_un.d_ptr +
_dl_rtld_map.l_info[DT_RPATH]->d_un.d_val);
}
/* Call the OS-dependent function to set up life so we can do things like /* Call the OS-dependent function to set up life so we can do things like
file access. It will call `dl_main' (below) to do all the real work file access. It will call `dl_main' (below) to do all the real work
@ -416,6 +420,23 @@ of this helper program; chances are you did not intend to run this program.\n",
_dl_rtld_libname.name = (const char *) main_map->l_addr + ph->p_vaddr; _dl_rtld_libname.name = (const char *) main_map->l_addr + ph->p_vaddr;
_dl_rtld_libname.next = NULL; _dl_rtld_libname.next = NULL;
_dl_rtld_map.l_libname = &_dl_rtld_libname; _dl_rtld_map.l_libname = &_dl_rtld_libname;
/* Ordinarilly, we would get additional names for the loader from
our DT_SONAME. This can't happen if we were actually linked as
a static executable (detect this case when we have no DYNAMIC).
If so, assume the filename component of the interpreter path to
be our SONAME, and add it to our name list. */
if (_dl_rtld_map.l_ld == NULL)
{
char *p = strrchr (_dl_rtld_libname.name, '/');
if (p)
{
_dl_rtld_libname2.name = p+1;
_dl_rtld_libname2.next = NULL;
_dl_rtld_libname.next = &_dl_rtld_libname2;
}
}
has_interp = 1; has_interp = 1;
break; break;
} }
@ -696,74 +717,70 @@ of this helper program; chances are you did not intend to run this program.\n",
for (map = _dl_loaded; map != NULL; map = map->l_next) for (map = _dl_loaded; map != NULL; map = map->l_next)
{ {
const char *strtab = const char *strtab;
(const char *) (map->l_addr
+ map->l_info[DT_STRTAB]->d_un.d_ptr);
ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG]; ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
ElfW(Verneed) *ent;
if (dyn != NULL) if (dyn == NULL)
continue;
strtab = (const char *)
(map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
if (first)
{ {
ElfW(Verneed) *ent = _dl_sysdep_message ("\n\tVersion information:\n", NULL);
(ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr); first = 0;
}
if (first) _dl_sysdep_message ("\t", (map->l_name[0]
{ ? map->l_name : _dl_argv[0]),
_dl_sysdep_message ("\n\tVersion information:\n", ":\n", NULL);
NULL);
first = 0;
}
_dl_sysdep_message ("\t", (map->l_name[0] while (1)
? map->l_name {
: _dl_argv[0]), ":\n", ElfW(Vernaux) *aux;
NULL); struct link_map *needed;
needed = find_needed (strtab + ent->vn_file);
aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
while (1) while (1)
{ {
ElfW(Vernaux) *aux; const char *fname = NULL;
struct link_map *needed;
needed = find_needed (strtab + ent->vn_file); _dl_sysdep_message ("\t\t",
aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux); strtab + ent->vn_file,
" (", strtab + aux->vna_name,
") ",
(aux->vna_flags
& VER_FLG_WEAK
? "[WEAK] " : ""),
"=> ", NULL);
while (1) if (needed != NULL
{ && match_version (strtab+aux->vna_name, needed))
const char *fname = NULL; fname = needed->l_name;
_dl_sysdep_message ("\t\t", _dl_sysdep_message (fname ?: "not found", "\n",
strtab + ent->vn_file, NULL);
" (", strtab + aux->vna_name,
") ",
(aux->vna_flags
& VER_FLG_WEAK
? "[WEAK] " : ""),
"=> ", NULL);
if (needed != NULL if (aux->vna_next == 0)
&& match_version (strtab + aux->vna_name, /* No more symbols. */
needed))
fname = needed->l_name;
_dl_sysdep_message (fname ?: "not found", "\n",
NULL);
if (aux->vna_next == 0)
/* No more symbols. */
break;
/* Next symbol. */
aux = (ElfW(Vernaux) *) ((char *) aux
+ aux->vna_next);
}
if (ent->vn_next == 0)
/* No more dependencies. */
break; break;
/* Next dependency. */ /* Next symbol. */
ent = (ElfW(Verneed) *) ((char *) ent aux = (ElfW(Vernaux) *) ((char *) aux
+ ent->vn_next); + aux->vna_next);
} }
if (ent->vn_next == 0)
/* No more dependencies. */
break;
/* Next dependency. */
ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);
} }
} }
} }

View File

@ -99,9 +99,9 @@ _nl_find_domain (dirname, locale, domainname)
language[_territory][+audience][+special][,[sponsor][_revision]] language[_territory][+audience][+special][,[sponsor][_revision]]
Beside the first all of them are allowed to be missing. If the Beside the first part all of them are allowed to be missing. If
full specified locale is not found, the less specific one are the full specified locale is not found, the less specific one are
looked for. The various part will be stripped of according to looked for. The various parts will be stripped off according to
the following order: the following order:
(1) revision (1) revision
(2) sponsor (2) sponsor

View File

@ -85,7 +85,7 @@ void free ();
# define strdup __strdup # define strdup __strdup
/* We need locking here since we can be called from different palces. */ /* We need locking here since we can be called from different palces. */
# include <libc-lock.h> # include <bits/libc-lock.h>
__libc_lock_define_initialized (static, lock); __libc_lock_define_initialized (static, lock);
#endif #endif

View File

@ -41,7 +41,7 @@ GLIBC_2.0 {
# functions with required interface outside normal name space # functions with required interface outside normal name space
_exit; __ivaliduser; __open_catalog; _exit; __ivaliduser; __open_catalog;
__argz_count; __argz_stringify; __argz_next; __argz_count; __argz_stringify; __argz_next;
__check_rhosts_file; __rcmd_errstr; __check_rhosts_file; __rcmd_errstr; __xpg_basename;
# functions from the experimental locale implementation # functions from the experimental locale implementation
__*_l; __newlocale; __duplocale; __freelocale; __*_l; __newlocale; __duplocale; __freelocale;

View File

@ -51,6 +51,12 @@ typedef struct _IO_FILE FILE;
#include <libio.h> #include <libio.h>
#ifdef __cplusplus
# define __STDIO_INLINE __inline
#else
# define __STDIO_INLINE extern __inline
#endif
/* The type of the second argument to `fgetpos' and `fsetpos'. */ /* The type of the second argument to `fgetpos' and `fsetpos'. */
typedef _G_fpos_t fpos_t; typedef _G_fpos_t fpos_t;
@ -235,36 +241,40 @@ extern int vsprintf __P ((char *__restrict __s,
_G_va_list __arg)); _G_va_list __arg));
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
extern __inline int __STDIO_INLINE int
vprintf (const char *__restrict __fmt, _G_va_list __arg) vprintf (const char *__restrict __fmt, _G_va_list __arg)
{ {
return vfprintf (stdout, __fmt, __arg); return vfprintf (stdout, __fmt, __arg);
} }
#endif /* Optimizing. */ #endif /* Optimizing. */
#if defined __USE_GNU || defined __USE_ISOC9X #if defined __USE_BSD || defined __USE_ISOC9X
/* Maximum chars of output to write in MAXLEN. */ /* Maximum chars of output to write in MAXLEN. */
extern int __snprintf __P ((char *__s, size_t __maxlen, extern int __snprintf __P ((char *__restrict __s, size_t __maxlen,
__const char *__format, ...)); __const char *__restrict __format, ...));
extern int snprintf __P ((char *__s, size_t __maxlen, extern int snprintf __P ((char *__restrict __s, size_t __maxlen,
__const char *__format, ...)); __const char *__restrict __format, ...));
extern int __vsnprintf __P ((char *__s, size_t __maxlen, extern int __vsnprintf __P ((char *__restrict __s, size_t __maxlen,
__const char *__format, _G_va_list __arg)); __const char *__restrict __format,
extern int vsnprintf __P ((char *__s, size_t __maxlen, _G_va_list __arg));
__const char *__format, _G_va_list __arg)); extern int vsnprintf __P ((char *__restrict __s, size_t __maxlen,
__const char *__restrict __format,
_G_va_list __arg));
#endif #endif
#ifdef __USE_GNU #ifdef __USE_GNU
/* Write formatted output to a string dynamically allocated with `malloc'. /* Write formatted output to a string dynamically allocated with `malloc'.
Store the address of the string in *PTR. */ Store the address of the string in *PTR. */
extern int vasprintf __P ((char **__ptr, __const char *__f, extern int vasprintf __P ((char **__restrict __ptr,
_G_va_list __arg)); __const char *__restrict __f, _G_va_list __arg));
extern int asprintf __P ((char **__ptr, __const char *__fmt, ...)); extern int asprintf __P ((char **__restrict __ptr,
__const char *__restrict __fmt, ...));
/* Write formatted output to a file descriptor. */ /* Write formatted output to a file descriptor. */
extern int vdprintf __P ((int __fd, __const char *__fmt, _G_va_list __arg)); extern int vdprintf __P ((int __fd, __const char *__restrict __fmt,
extern int dprintf __P ((int __fd, __const char *__fmt, ...)); _G_va_list __arg));
extern int dprintf __P ((int __fd, __const char *__restrict __fmt, ...));
#endif #endif
@ -279,19 +289,24 @@ extern int sscanf __P ((__const char *__restrict __s,
#ifdef __USE_GNU #ifdef __USE_GNU
/* Read formatted input from S into argument list ARG. */ /* Read formatted input from S into argument list ARG. */
extern int __vfscanf __P ((FILE *__s, __const char *__format, extern int __vfscanf __P ((FILE *__restrict __s,
__const char *__restrict __format,
_G_va_list __arg)); _G_va_list __arg));
extern int vfscanf __P ((FILE *__s, __const char *__format, extern int vfscanf __P ((FILE *__restrict __s,
__const char *__restrict __format,
_G_va_list __arg)); _G_va_list __arg));
/* Read formatted input from stdin into argument list ARG. */ /* Read formatted input from stdin into argument list ARG. */
extern int __vscanf __P ((__const char *__format, _G_va_list __arg)); extern int __vscanf __P ((__const char *__restrict __format,
extern int vscanf __P ((__const char *__format, _G_va_list __arg)); _G_va_list __arg));
extern int vscanf __P ((__const char *__restrict __format, _G_va_list __arg));
/* Read formatted input from S into argument list ARG. */ /* Read formatted input from S into argument list ARG. */
extern int __vsscanf __P ((__const char *__s, __const char *__format, extern int __vsscanf __P ((__const char *__restrict __s,
__const char *__restrict __format,
_G_va_list __arg)); _G_va_list __arg));
extern int vsscanf __P ((__const char *__s, __const char *__format, extern int vsscanf __P ((__const char *__restrict __s,
__const char *__restrict __format,
_G_va_list __arg)); _G_va_list __arg));
#endif /* Use GNU. */ #endif /* Use GNU. */
@ -308,7 +323,7 @@ extern int getchar __P ((void));
#define getc(_fp) _IO_getc (_fp) #define getc(_fp) _IO_getc (_fp)
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
extern __inline int __STDIO_INLINE int
getchar (void) getchar (void)
{ {
return _IO_getc (stdin); return _IO_getc (stdin);
@ -321,13 +336,13 @@ extern int getc_unlocked __P ((FILE *__stream));
extern int getchar_unlocked __P ((void)); extern int getchar_unlocked __P ((void));
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
extern __inline int __STDIO_INLINE int
getc_unlocked (FILE *__fp) getc_unlocked (FILE *__fp)
{ {
return _IO_getc_unlocked (__fp); return _IO_getc_unlocked (__fp);
} }
extern __inline int __STDIO_INLINE int
getchar_unlocked (void) getchar_unlocked (void)
{ {
return _IO_getc_unlocked (stdin); return _IO_getc_unlocked (stdin);
@ -348,7 +363,7 @@ extern int putchar __P ((int __c));
#define putc(_ch, _fp) _IO_putc (_ch, _fp) #define putc(_ch, _fp) _IO_putc (_ch, _fp)
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
extern __inline int __STDIO_INLINE int
putchar (int __c) putchar (int __c)
{ {
return _IO_putc (__c, stdout); return _IO_putc (__c, stdout);
@ -360,7 +375,7 @@ putchar (int __c)
extern int fputc_unlocked __P ((int __c, FILE *__stream)); extern int fputc_unlocked __P ((int __c, FILE *__stream));
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
extern __inline int __STDIO_INLINE int
fputc_unlocked (int __c, FILE *__stream) fputc_unlocked (int __c, FILE *__stream)
{ {
return _IO_putc_unlocked (__c, __stream); return _IO_putc_unlocked (__c, __stream);
@ -374,13 +389,13 @@ extern int putc_unlocked __P ((int __c, FILE *__stream));
extern int putchar_unlocked __P ((int __c)); extern int putchar_unlocked __P ((int __c));
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
extern __inline int __STDIO_INLINE int
putc_unlocked (int __c, FILE *__stream) putc_unlocked (int __c, FILE *__stream)
{ {
return _IO_putc_unlocked (__c, __stream); return _IO_putc_unlocked (__c, __stream);
} }
extern __inline int __STDIO_INLINE int
putchar_unlocked (int __c) putchar_unlocked (int __c)
{ {
return _IO_putc_unlocked (__c, stdout); return _IO_putc_unlocked (__c, stdout);
@ -423,7 +438,7 @@ _IO_ssize_t __getline __P ((char **__lineptr, size_t *__n, FILE *__stream));
_IO_ssize_t getline __P ((char **__lineptr, size_t *__n, FILE *__stream)); _IO_ssize_t getline __P ((char **__lineptr, size_t *__n, FILE *__stream));
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
extern __inline _IO_ssize_t __STDIO_INLINE _IO_ssize_t
getline (char **__lineptr, size_t *__n, FILE *__stream) getline (char **__lineptr, size_t *__n, FILE *__stream)
{ {
return __getdelim (__lineptr, __n, '\n', __stream); return __getdelim (__lineptr, __n, '\n', __stream);
@ -488,13 +503,13 @@ extern int feof_unlocked __P ((FILE *__stream));
extern int ferror_unlocked __P ((FILE *__stream)); extern int ferror_unlocked __P ((FILE *__stream));
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
extern __inline int __STDIO_INLINE int
feof_unlocked (FILE *__stream) feof_unlocked (FILE *__stream)
{ {
return _IO_feof_unlocked (__stream); return _IO_feof_unlocked (__stream);
} }
extern __inline int __STDIO_INLINE int
ferror_unlocked (FILE *__stream) ferror_unlocked (FILE *__stream)
{ {
return _IO_ferror_unlocked (__stream); return _IO_ferror_unlocked (__stream);
@ -579,6 +594,9 @@ extern void funlockfile __P ((FILE *__stream));
__END_DECLS __END_DECLS
/* Define helper macro. */
#undef __STDIO_INLINE
#endif /* <stdio.h> included. */ #endif /* <stdio.h> included. */
#endif /* !_STDIO_H */ #endif /* !_STDIO_H */

View File

@ -1,171 +1,190 @@
/* /*
* Defines the valid international currency symbols according to ISO-4217. * Defines the valid international currency symbols according to ISO 4217.
* This is used in monetary.c(monetary_check). * This is used in monetary.c(monetary_check).
* *
* If you find something missing or wrong contact <bug-glibc@prep.ai.mit.edu> * If you find something missing or wrong contact <bug-glibc@prep.ai.mit.edu>
* *
* !!! The list has to be sorted !!! * !!! The list has to be sorted !!!
*/ */
DEFINE_INT_CURR("AED ") /* United Arab Emirates */ DEFINE_INT_CURR("ADP ") /* Andorran Peseta */
DEFINE_INT_CURR("AFA ") /* Afghanistan */ DEFINE_INT_CURR("AED ") /* United Arab Emirates Dirham */
DEFINE_INT_CURR("ALL ") /* Albania */ DEFINE_INT_CURR("AFA ") /* Afghanistan Afgani */
DEFINE_INT_CURR("ALL ") /* Albanian Lek */
DEFINE_INT_CURR("AMD ") /* Armenia Dram */
DEFINE_INT_CURR("ANG ") /* Netherlands Antilles */ DEFINE_INT_CURR("ANG ") /* Netherlands Antilles */
DEFINE_INT_CURR("AOK ") /* Angola */ DEFINE_INT_CURR("AOK ") /* Angolan Kwanza */
DEFINE_INT_CURR("ARP ") /* Argentina */ DEFINE_INT_CURR("AON ") /* Angolan New Kwanza */
DEFINE_INT_CURR("ATS ") /* Austria */ DEFINE_INT_CURR("ARP ") /* Argentine Peso */
DEFINE_INT_CURR("AUD ") /* Australia */ DEFINE_INT_CURR("ATS ") /* Austrian Schilling */
DEFINE_INT_CURR("BBD ") /* Barbados */ DEFINE_INT_CURR("AUD ") /* Australian Dollar */
DEFINE_INT_CURR("BDT ") /* Bangladesh */ DEFINE_INT_CURR("AZM ") /* Azerbaijan Manat */
DEFINE_INT_CURR("BEF ") /* Belgium */ DEFINE_INT_CURR("BBD ") /* Barbados Dollar */
DEFINE_INT_CURR("BGL ") /* Bulgaria */ DEFINE_INT_CURR("BDT ") /* Bangladesh Taka */
DEFINE_INT_CURR("BHD ") /* Bahrain */ DEFINE_INT_CURR("BEF ") /* Belgian Franc */
DEFINE_INT_CURR("BGL ") /* Bulgarian Lev */
DEFINE_INT_CURR("BHD ") /* Bahraini Dinar */
DEFINE_INT_CURR("BIF ") /* Burundi */ DEFINE_INT_CURR("BIF ") /* Burundi */
DEFINE_INT_CURR("BMD ") /* Burmuda */ DEFINE_INT_CURR("BMD ") /* Burmudian Dollar */
DEFINE_INT_CURR("BND ") /* Brunei */ DEFINE_INT_CURR("BND ") /* Brunei Dollar */
DEFINE_INT_CURR("BOP ") /* Bolivia */ DEFINE_INT_CURR("BOP ") /* Bolivian Boliviano */
DEFINE_INT_CURR("BRC ") /* Brazil */ DEFINE_INT_CURR("BPS ") /* Canton and Enderbury Islands */
DEFINE_INT_CURR("BSD ") /* Bahamas */ DEFINE_INT_CURR("BRC ") /* Brazil Real */
DEFINE_INT_CURR("BRL ") /* Brazil Cruzeiro */
DEFINE_INT_CURR("BRR ") /* Brazil Real */
DEFINE_INT_CURR("BSD ") /* Bahamas Dollar */
DEFINE_INT_CURR("BTN ") /* Bhutan Ngultrum */
DEFINE_INT_CURR("BUK ") /* Burma */ DEFINE_INT_CURR("BUK ") /* Burma */
DEFINE_INT_CURR("BWP ") /* Botswana */ DEFINE_INT_CURR("BWP ") /* Botswana Pula */
DEFINE_INT_CURR("BZD ") /* Belize */ DEFINE_INT_CURR("BZD ") /* Belize Dollar */
DEFINE_INT_CURR("CAD ") /* Canada */ DEFINE_INT_CURR("CAD ") /* Canadian Dollar */
DEFINE_INT_CURR("CHF ") /* Switzerland, Liechtenstein */ DEFINE_INT_CURR("CFP ") /* French Pacific Island Franc */
DEFINE_INT_CURR("CLP ") /* Chile */ DEFINE_INT_CURR("CHF ") /* Swiss Franc (Liechtenstein) */
DEFINE_INT_CURR("CNY ") /* China */ DEFINE_INT_CURR("CLP ") /* Chilean Peso */
DEFINE_INT_CURR("COP ") /* Colombia */ DEFINE_INT_CURR("CNY ") /* China Yuan Renminbi */
DEFINE_INT_CURR("CRC ") /* Costa Rica */ DEFINE_INT_CURR("COP ") /* Colombian Peso */
DEFINE_INT_CURR("CSK ") /* Czechoslovakia */ DEFINE_INT_CURR("CRC ") /* Costa Rican Colon */
DEFINE_INT_CURR("CUP ") /* Cuba */ DEFINE_INT_CURR("CUP ") /* Cuban Peso */
DEFINE_INT_CURR("CVE ") /* Cape Verde */ DEFINE_INT_CURR("CVE ") /* Cape Verde Escudo */
DEFINE_INT_CURR("CYP ") /* Cyprus */ DEFINE_INT_CURR("CYP ") /* Cypriot Pound */
DEFINE_INT_CURR("DEM ") /* Germany */ DEFINE_INT_CURR("CZK ") /* Czech Koruna */
DEFINE_INT_CURR("DJF ") /* Djibouti */ DEFINE_INT_CURR("DEM ") /* German Mark */
DEFINE_INT_CURR("DKK ") /* Denmark */ DEFINE_INT_CURR("DJF ") /* Djibouti Franc */
DEFINE_INT_CURR("DKK ") /* Danish Krone (Faroe Islands, Greenland) */
DEFINE_INT_CURR("DOP ") /* Dominican Republic */ DEFINE_INT_CURR("DOP ") /* Dominican Republic */
DEFINE_INT_CURR("DZD ") /* Algeria */ DEFINE_INT_CURR("DZD ") /* Algerian Dinar */
DEFINE_INT_CURR("ECS ") /* Ecuador */ DEFINE_INT_CURR("ECS ") /* Ecuadoran Sucre */
DEFINE_INT_CURR("EEK ") /* Estonia */ DEFINE_INT_CURR("EEK ") /* Estonian Kroon */
DEFINE_INT_CURR("EGP ") /* Egypt */ DEFINE_INT_CURR("EGP ") /* Egyptian Pound */
DEFINE_INT_CURR("ESP ") /* Spain */ DEFINE_INT_CURR("ESP ") /* Spanish Peseta */
DEFINE_INT_CURR("ETB ") /* Ethiopia */ DEFINE_INT_CURR("ETB ") /* Ethiopian Birr */
DEFINE_INT_CURR("FIM ") /* Finland */ DEFINE_INT_CURR("EUR ") /* European Union Euro */
DEFINE_INT_CURR("FJD ") /* Fiji */ DEFINE_INT_CURR("FIM ") /* Finnish Markka */
DEFINE_INT_CURR("FKP ") /* Falkland Islands (Malvinas) */ DEFINE_INT_CURR("FJD ") /* Fiji Dollar */
DEFINE_INT_CURR("FRF ") /* France */ DEFINE_INT_CURR("FKP ") /* Falkland Islands Pound (Malvinas) */
DEFINE_INT_CURR("GBP ") /* Great Britain */ DEFINE_INT_CURR("FRF ") /* French Franc */
DEFINE_INT_CURR("GHC ") /* Ghana */ DEFINE_INT_CURR("GBP ") /* British Pound */
DEFINE_INT_CURR("GIP ") /* Gibraltar */ DEFINE_INT_CURR("GEK ") /* Georgia Lari */
DEFINE_INT_CURR("GMD ") /* Gambia */ DEFINE_INT_CURR("GHC ") /* Ghana Cedi */
DEFINE_INT_CURR("GNS ") /* Guinea */ DEFINE_INT_CURR("GIP ") /* Gibraltar Pound */
DEFINE_INT_CURR("GQE ") /* Equatorial Guinea */ DEFINE_INT_CURR("GMD ") /* Gambian Dalasi */
DEFINE_INT_CURR("GRD ") /* Greece */ DEFINE_INT_CURR("GNS ") /* Guinea Syli */
DEFINE_INT_CURR("GTQ ") /* Guatemala */ DEFINE_INT_CURR("GQE ") /* Equatorial Guinea Ekwele */
DEFINE_INT_CURR("GWP ") /* Guinea-Bissau */ DEFINE_INT_CURR("GRD ") /* Greek Drachma */
DEFINE_INT_CURR("GYD ") /* Guyana */ DEFINE_INT_CURR("GTQ ") /* Guatemala Quetzal */
DEFINE_INT_CURR("HKD ") /* Hong Kong */ DEFINE_INT_CURR("GWP ") /* Guinea-Bissau Peso */
DEFINE_INT_CURR("HNL ") /* Honduras */ DEFINE_INT_CURR("GYD ") /* Guyana Dollar */
DEFINE_INT_CURR("HRD ") /* Croatia */ DEFINE_INT_CURR("HKD ") /* Hong Kong Dollar */
DEFINE_INT_CURR("HTG ") /* Haiti */ DEFINE_INT_CURR("HNL ") /* Honduras Lempira */
DEFINE_INT_CURR("HUF ") /* Hungary */ DEFINE_INT_CURR("HRK ") /* Croatia Kuna */
DEFINE_INT_CURR("IDR ") /* Indonesia */ DEFINE_INT_CURR("HTG ") /* Haiti Gourde */
DEFINE_INT_CURR("IEP ") /* Ireland */ DEFINE_INT_CURR("HUF ") /* Hungarian Forint */
DEFINE_INT_CURR("ILS ") /* Israel */ DEFINE_INT_CURR("IDR ") /* Indonesia Rupiah */
DEFINE_INT_CURR("INR ") /* India, Bhutan */ DEFINE_INT_CURR("IEP ") /* Irish Pound */
DEFINE_INT_CURR("IQD ") /* Iraq */ DEFINE_INT_CURR("ILS ") /* Israeli Shekel */
DEFINE_INT_CURR("IRR ") /* Iran */ DEFINE_INT_CURR("INR ") /* Indian Rupee (Bhutan) */
DEFINE_INT_CURR("ISK ") /* Iceland */ DEFINE_INT_CURR("IQD ") /* Iraqi Dinar */
DEFINE_INT_CURR("ITL ") /* Italy */ DEFINE_INT_CURR("IRR ") /* Iranian Rial */
DEFINE_INT_CURR("JMD ") /* Jamaica */ DEFINE_INT_CURR("ISK ") /* Iceland Krona */
DEFINE_INT_CURR("JOD ") /* Jordan */ DEFINE_INT_CURR("ITL ") /* Italian Lira (San Marino, Vatican City) */
DEFINE_INT_CURR("JPY ") /* Japan */ DEFINE_INT_CURR("JMD ") /* Jamaican Dollar */
DEFINE_INT_CURR("KES ") /* Kenya */ DEFINE_INT_CURR("JOD ") /* Jordanian Dinar */
DEFINE_INT_CURR("KHR ") /* Democratic Kampuchea */ DEFINE_INT_CURR("JPY ") /* Japanese Yen */
DEFINE_INT_CURR("KMF ") /* Comoros */ DEFINE_INT_CURR("KES ") /* Kenyan Shilling */
DEFINE_INT_CURR("KPW ") /* Democratic People's of Korea */ DEFINE_INT_CURR("KGS ") /* Kyrgyzstan Som */
DEFINE_INT_CURR("KRW ") /* Republic of Korea */ DEFINE_INT_CURR("KHR ") /* Democratic Kampuchea Riel */
DEFINE_INT_CURR("KWD ") /* Kuwait */ DEFINE_INT_CURR("KMF ") /* Comoros Franc */
DEFINE_INT_CURR("KPW ") /* Democratic People's of Korea Won */
DEFINE_INT_CURR("KRW ") /* Republic of Korea Won */
DEFINE_INT_CURR("KWD ") /* Kuwaiti Dinar */
DEFINE_INT_CURR("KYD ") /* Cayman Islands */ DEFINE_INT_CURR("KYD ") /* Cayman Islands */
DEFINE_INT_CURR("LAK ") /* Lao People's Democratic Republic */ DEFINE_INT_CURR("KZT ") /* Kazakhstan Tenge */
DEFINE_INT_CURR("LBP ") /* Lebanon */ DEFINE_INT_CURR("LAK ") /* Lao People's Democratic Republic New Kip */
DEFINE_INT_CURR("LKR ") /* Sri Lanka */ DEFINE_INT_CURR("LBP ") /* Lebanese Pound */
DEFINE_INT_CURR("LRD ") /* Liberia */ DEFINE_INT_CURR("LKR ") /* Sri Lankan Rupee */
DEFINE_INT_CURR("LSM ") /* Lesotho */ DEFINE_INT_CURR("LRD ") /* Liberian Dollar */
DEFINE_INT_CURR("LTL ") /* Lithuania */ DEFINE_INT_CURR("LSM ") /* Lesotho Maloti */
DEFINE_INT_CURR("LUF ") /* Luxembourg */ DEFINE_INT_CURR("LTL ") /* Lithuanian Litas */
DEFINE_INT_CURR("LVL ") /* Latvia */ DEFINE_INT_CURR("LUF ") /* Luxembourg Franc */
DEFINE_INT_CURR("LYD ") /* Libyan Arab Jamahiriya */ DEFINE_INT_CURR("LVL ") /* Latvia Lat */
DEFINE_INT_CURR("MAD ") /* Morocco */ DEFINE_INT_CURR("LYD ") /* Libyan Arab Jamahiriya Dinar */
DEFINE_INT_CURR("MGF ") /* Madagascar */ DEFINE_INT_CURR("MAD ") /* Moroccan Dirham */
DEFINE_INT_CURR("MLF ") /* Mali */ DEFINE_INT_CURR("MDL ") /* Moldova Lei */
DEFINE_INT_CURR("MNT ") /* Mongolia */ DEFINE_INT_CURR("MGF ") /* Madagasy Franc */
DEFINE_INT_CURR("MOP ") /* Macau */ DEFINE_INT_CURR("MLF ") /* Mali Franc */
DEFINE_INT_CURR("MRO ") /* Mauritania */ DEFINE_INT_CURR("MMK ") /* Myanmar Kyat */
DEFINE_INT_CURR("MTP ") /* Malta */ DEFINE_INT_CURR("MNT ") /* Mongolia Tugrik */
DEFINE_INT_CURR("MUR ") /* Mauritius */ DEFINE_INT_CURR("MOP ") /* Macau Pataca */
DEFINE_INT_CURR("MVR ") /* Maldives */ DEFINE_INT_CURR("MRO ") /* Mauritania Ouguiya */
DEFINE_INT_CURR("MWK ") /* Malawi */ DEFINE_INT_CURR("MTP ") /* Maltese Lira */
DEFINE_INT_CURR("MXP ") /* Mexico */ DEFINE_INT_CURR("MUR ") /* Mauritius Rupee */
DEFINE_INT_CURR("MYR ") /* Malaysia */ DEFINE_INT_CURR("MVR ") /* Maldives Rupee */
DEFINE_INT_CURR("MZM ") /* Mozambique */ DEFINE_INT_CURR("MWK ") /* Malawi Kwacha */
DEFINE_INT_CURR("NGN ") /* Nigeria */ DEFINE_INT_CURR("MXP ") /* Mexican Peso */
DEFINE_INT_CURR("NIC ") /* Nicaragua */ DEFINE_INT_CURR("MYR ") /* Malaysian Ringgit */
DEFINE_INT_CURR("NLG ") /* Netherlands */ DEFINE_INT_CURR("MZM ") /* Mozambique Metical */
DEFINE_INT_CURR("NOK ") /* Norway */ DEFINE_INT_CURR("NGN ") /* Nigeria Naira */
DEFINE_INT_CURR("NPR ") /* Nepal */ DEFINE_INT_CURR("NIC ") /* Nicaragua Cordoba */
DEFINE_INT_CURR("NZD ") /* New Zealand */ DEFINE_INT_CURR("NLG ") /* Netherlands Guilder */
DEFINE_INT_CURR("OMR ") /* Oman */ DEFINE_INT_CURR("NOK ") /* Norwegian Krone */
DEFINE_INT_CURR("PAB ") /* Panama */ DEFINE_INT_CURR("NPR ") /* Nepalese Rupee */
DEFINE_INT_CURR("PES ") /* Peru */ DEFINE_INT_CURR("NZD ") /* New Zealand Dollar */
DEFINE_INT_CURR("PGK ") /* Papau New Guinea */ DEFINE_INT_CURR("OMR ") /* Omani Rial */
DEFINE_INT_CURR("PHP ") /* Philippines */ DEFINE_INT_CURR("PAB ") /* Panamaniam Balboa */
DEFINE_INT_CURR("PKR ") /* Pakistan */ DEFINE_INT_CURR("PEN ") /* Peruvian New Sol */
DEFINE_INT_CURR("PLZ ") /* Poland */ DEFINE_INT_CURR("PGK ") /* Papau New Guinea Kina */
DEFINE_INT_CURR("PTE ") /* Portugal */ DEFINE_INT_CURR("PHP ") /* Philippines Peso */
DEFINE_INT_CURR("PYG ") /* Paraguay */ DEFINE_INT_CURR("PKR ") /* Pakistan Rupee */
DEFINE_INT_CURR("QAR ") /* Qatar */ DEFINE_INT_CURR("PLZ ") /* Polish Zloty */
DEFINE_INT_CURR("ROL ") /* Romania */ DEFINE_INT_CURR("PTE ") /* Portugese Escudo */
DEFINE_INT_CURR("RUR ") /* Russia */ DEFINE_INT_CURR("PYG ") /* Paraguay Guarani */
DEFINE_INT_CURR("RWF ") /* Rwanda */ DEFINE_INT_CURR("QAR ") /* Qatar Rial */
DEFINE_INT_CURR("SAR ") /* Saudi Arabia */ DEFINE_INT_CURR("ROL ") /* Romanian Leu */
DEFINE_INT_CURR("SBD ") /* Solomon Islands */ DEFINE_INT_CURR("RUR ") /* Russian Ruble */
DEFINE_INT_CURR("SCR ") /* Seychelles */ DEFINE_INT_CURR("RWF ") /* Rwanda Franc */
DEFINE_INT_CURR("SDP ") /* Sudan */ DEFINE_INT_CURR("SAR ") /* Saudi Arabia Riyal */
DEFINE_INT_CURR("SEK ") /* Sweden */ DEFINE_INT_CURR("SBD ") /* Solomon Islands Dollar */
DEFINE_INT_CURR("SGD ") /* Singapore */ DEFINE_INT_CURR("SCR ") /* Seychelles Rupee */
DEFINE_INT_CURR("SHP ") /* St. Helena */ DEFINE_INT_CURR("SDP ") /* Sudanese Pound */
DEFINE_INT_CURR("SIT ") /* Slovenia */ DEFINE_INT_CURR("SEK ") /* Swedish Krona */
DEFINE_INT_CURR("SLL ") /* Sierra Leone */ DEFINE_INT_CURR("SGD ") /* Singapore Dollar */
DEFINE_INT_CURR("SOS ") /* Somalia */ DEFINE_INT_CURR("SHP ") /* St. Helena Pound */
DEFINE_INT_CURR("SRG ") /* Suriname */ DEFINE_INT_CURR("SIT ") /* Slovenian Tolar */
DEFINE_INT_CURR("STD ") /* Sao Tome and Principe */ DEFINE_INT_CURR("SKK ") /* Slovakian Koruna */
DEFINE_INT_CURR("SUR ") /* Ukrainian, Byelorussion */ DEFINE_INT_CURR("SLL ") /* Sierra Leone Leone */
DEFINE_INT_CURR("SVC ") /* El Salvador */ DEFINE_INT_CURR("SOS ") /* Somalia Schilling */
DEFINE_INT_CURR("SYP ") /* Syrian Arab Republic */ DEFINE_INT_CURR("SRG ") /* Suriname Guilder */
DEFINE_INT_CURR("SZL ") /* Swaziland */ DEFINE_INT_CURR("STD ") /* Sao Tome and Principe Dobra */
DEFINE_INT_CURR("THB ") /* Thailand */ DEFINE_INT_CURR("SUR ") /* Soviet Union Rubel (Ukrainian, Byelorussion) */
DEFINE_INT_CURR("TND ") /* Tunisia */ DEFINE_INT_CURR("SVC ") /* El Salvador Colon */
DEFINE_INT_CURR("TOP ") /* Tonga */ DEFINE_INT_CURR("SYP ") /* Syrian Arab Republic Pound */
DEFINE_INT_CURR("TPE ") /* East Timor */ DEFINE_INT_CURR("SZL ") /* Swaziland Lilangeni */
DEFINE_INT_CURR("TRL ") /* Turkey */ DEFINE_INT_CURR("THB ") /* Thai Baht */
DEFINE_INT_CURR("TMM ") /* Turkmenistan Manet */
DEFINE_INT_CURR("TND ") /* Tunisian Dinar */
DEFINE_INT_CURR("TOP ") /* Tonga Pa'Anga */
DEFINE_INT_CURR("TPE ") /* East Timor Escudo */
DEFINE_INT_CURR("TRL ") /* Turkish Lira */
DEFINE_INT_CURR("TTD ") /* Trinidad and Tobago */ DEFINE_INT_CURR("TTD ") /* Trinidad and Tobago */
DEFINE_INT_CURR("TWD ") /* Taiwan, Province of China */ DEFINE_INT_CURR("TWD ") /* Taiwan, Province of China Dollar */
DEFINE_INT_CURR("TZS ") /* United Republic of Tanzania */ DEFINE_INT_CURR("TZS ") /* United Republic of Tanzania Shilling */
DEFINE_INT_CURR("UGS ") /* Uganda */ DEFINE_INT_CURR("UAK ") /* Ukraine Hryvna */
DEFINE_INT_CURR("USD ") /* United States */ DEFINE_INT_CURR("UGS ") /* Ugandan Shilling */
DEFINE_INT_CURR("UYP ") /* Uruguay */ DEFINE_INT_CURR("USD ") /* United States Dollar */
DEFINE_INT_CURR("VEB ") /* Venezuela */ DEFINE_INT_CURR("UYP ") /* Uruguay Peso */
DEFINE_INT_CURR("VND ") /* Viet Nam */ DEFINE_INT_CURR("UYU ") /* Uruguay New Peso */
DEFINE_INT_CURR("VUV ") /* Vanuatu */ DEFINE_INT_CURR("UZS ") /* Uzbekistan Sum */
DEFINE_INT_CURR("WST ") /* Samoa */ DEFINE_INT_CURR("VEB ") /* Venezuelan Bolivar */
DEFINE_INT_CURR("XAF ") /* United Republic of Cameroon, Central African Republic, Chad, Congo, Gabon */ DEFINE_INT_CURR("VND ") /* Viet Nam Dong */
DEFINE_INT_CURR("XCD ") /* Antiqua, Dominica, Grenada, Montserrat, St. Kitts-Nevis-Anguilla, Saint Lucia, Saint Vincent and the Grenadines */ DEFINE_INT_CURR("VUV ") /* Vanuatu Vatu */
DEFINE_INT_CURR("XOF ") /* Benin, Ivory Coast, Niger, Senegal, Togo, Upper Volta */ DEFINE_INT_CURR("WST ") /* Samoa Tala */
DEFINE_INT_CURR("XAF ") /* Central African Franc (United Republic of Cameroon, Central African Republic, Chad, Congo, Gabon) */
DEFINE_INT_CURR("XCD ") /* East Caribbean Dollar (Antiqua, Dominica, Grenada, Montserrat, St. Kitts-Nevis-Anguilla, Saint Lucia, Saint Vincent and the Grenadines) */
DEFINE_INT_CURR("XDS ") /* St. Christopher Dollar */
DEFINE_INT_CURR("XOF ") /* West African Franc (Benin, Ivory Coast, Niger, Senegal, Togo, Upper Volta) */
DEFINE_INT_CURR("XPF ") /* French polynesia, New Caledonia, Wallis and Futuna Islands */ DEFINE_INT_CURR("XPF ") /* French polynesia, New Caledonia, Wallis and Futuna Islands */
DEFINE_INT_CURR("YDD ") /* Democratic Yemen */ DEFINE_INT_CURR("YDD ") /* Yemini Dinar (Democratic Yemen) */
DEFINE_INT_CURR("YER ") /* Yemen */ DEFINE_INT_CURR("YER ") /* Yemeni Rial */
DEFINE_INT_CURR("YUD ") /* Yugoslavia */ DEFINE_INT_CURR("ZAR ") /* South Africa Rand (Lesotho, Namibia) */
DEFINE_INT_CURR("ZAL ") /* South Africa */ DEFINE_INT_CURR("ZMK ") /* Zambian Kwacha */
DEFINE_INT_CURR("ZAR ") /* Lesotho, Namibia */ DEFINE_INT_CURR("ZRZ ") /* Zaire Zaire */
DEFINE_INT_CURR("ZMK ") /* Zambia */ DEFINE_INT_CURR("ZWD ") /* Zimbabwe Dollar */
DEFINE_INT_CURR("ZRZ ") /* Zaire */
DEFINE_INT_CURR("ZWD ") /* Zimbabwe */

View File

@ -127,7 +127,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
#endif #endif
filedata = (void *) __mmap ((caddr_t) 0, st.st_size, PROT_READ, filedata = (void *) __mmap ((caddr_t) 0, st.st_size, PROT_READ,
MAP_FILE|MAP_COPY|MAP_INHERIT, fd, 0); MAP_FILE|MAP_COPY|MAP_INHERIT, fd, 0);
if (filedata == MAP_FAILED) if ((void *) filedata == MAP_FAILED)
{ {
if (errno == ENOSYS) if (errno == ENOSYS)
{ {

View File

@ -1167,19 +1167,131 @@ translations from the file
@end smallexample @end smallexample
From the above descriptions it should be clear which component of this From the above descriptions it should be clear which component of this
filename is determined fromby which source. filename is determined by which source.
@c Describe: In the above example we assumed that the @code{LANGUAGE} environment
@c * message inheritence variable to @code{de}. This might be an appropriate selection but what
@c * locale aliasing happens if the user wants to use @code{LC_ALL} because of the wider
@c * character set dependence usability and here the required value is @code{de_DE.ISO-8859-1}? We
already mentioned above that a situation like this is not infrequent.
E.g., a person might prefer reading a dialect and if this is not
available fall back on the standard language.
The @code{gettext} functions know about situations like this and can
handle them gracefully. The functions recognize the format of the value
of the environment variable. It can split the value is different pieces
and by leaving out the only or the other part it can construct new
values. This happens of course in a predictable way. To understand
this one must know the format of the environment variable value. There
are to more or less standardized forms:
@table @emph
@item X/Open Format
@code{language[_territory[.codeset]][@@modifier]}
@item CEN Format (European Community Standard)
@code{language[_territory][+audience][+special][,[sponsor][_revision]]}
@end table
The functions will automatically recognize which format is used. Less
specific locale names will be stripped of in the order of the following
list:
@enumerate
@item
@code{revision}
@item
@code{sponsor}
@item
@code{special}
@item
@code{codeset}
@item
@code{normalized codeset}
@item
@code{territory}
@item
@code{audience}/@code{modifier}
@end enumerate
From the last entry one can see that the meaning of the @code{modifer}
field in the X/Open format and the @code{audience} format have the same
meaning. Beside one can see that the @code{language} field for obvious
reasons never will be dropped.
The only new thing is the @code{normalized codeset} entry. This is
another goodie which is introduced to help reducing the chaos which
derives from the inability of the people to standardize the names of
character sets. Instead of @w{ISO-8859-1} one can often see @w{8859-1},
@w{88591}, @w{iso8859-1}, or @w{iso_8859-1}. The @code{normalized
codeset} value is generated from the user-provided character set name by
applying the following rules:
@enumerate
@item
Remove all characters beside numbers and letters.
@item
Fold letters to lowercase.
@item
If the same only contains digits prepend the string @code{"iso"}.
@end enumerate
@noindent
So all of the above name will be normalized to @code{iso88591}. This
allows the program user much more freely choosing the locale name.
Even this extended functionality still does not help to solve the
problem that completely different names can be used to denote the same
locale (e.g., @code{de} and @code{german}). To be of help in this
situation the locale implementation and also the @code{gettext}
functions know about aliases.
The file @file{/usr/share/locale/locale.alias} (replace @file{/usr} with
whatever prefix you used for configuring the C library) contains a
mapping of alternative names to more regular names. The system manager
is free to add new entries to fill her/his own needs. The selected
locale from the environment is compared with the entries in the first
column of this file ignoring the case. If they match the value of the
second column is used instead for the further handling.
In the description of the format of the environment variables we already
mentioned the character set as a factor in the selection of the message
catalog. In fact, only catalogs which contain text written using the
character set of the system/program can be used (directly; there will
come a solution for this some day). This means for the user that s/he
will always have to take care for this. If in the collection of the
message catalogs there are files for the same language but coded using
different character sets the user has to be careful.
@node Helper programs for gettext @node Helper programs for gettext
@subsection Programs to handle message catalogs for @code{gettext} @subsection Programs to handle message catalogs for @code{gettext}
@c Describe: The GNU C Library does not contain the source code for the programs to
@c * msgfmt handle message catalogs for the @code{gettext} functions. As part of
@c * xgettext the GNU project the GNU gettext package contains everything the
@c Mention: developer needs. The functionality provided by the tools in this
@c * other programs from GNU gettext package by far exceeds the abilities of the @code{gencat} program
described above for the @code{catgets} functions.
There is a program @code{msgfmt} which is the equivalent program to the
@code{gencat} program. It generates from the human-readable and
-editable form of the message catalog a binary file which can be used by
the @code{gettext} functions. But there are several more programs
available.
The @code{xgettext} program can be used to automatically extract the
translatable messages from a source file. I.e., the programmer need not
take care for the translations and the list of messages which have to be
translated. S/He will simply wrap the translatable string in calls to
@code{gettext} et.al and the rest will be done by @code{xgettext}. This
program has a lot of option which help to customize the output or do
help to understand the input better.
Other programs help to manage development cycle when new messages appear
in the source files or when a new translation of the messages appear.
here it should only be noted that using all the tools in GNu gettext it
is possible to @emph{completely} automize the handling of message
catalog. Beside marking the translatable string in the source code and
generating the translations the developers do not have anything to do
themself.

View File

@ -4705,7 +4705,7 @@ identities (void)
identities1_test (0, 0); identities1_test (0, 0);
identities1_test (-1, CHOOSE (1e-18L, 0, 1e-7)); identities1_test (-1, CHOOSE (1e-18L, 0, 1e-7));
identities2_test (0.2L, CHOOSE (0, 1e-16, 0)); identities2_test (0.2L, CHOOSE (1e-19L, 1e-16, 0));
identities2_test (0.9L, CHOOSE (0, 1e-15, 0)); identities2_test (0.9L, CHOOSE (0, 1e-15, 0));
identities2_test (0, 0); identities2_test (0, 0);
identities2_test (-1, CHOOSE (1e-18L, 1e-15, 0)); identities2_test (-1, CHOOSE (1e-18L, 1e-15, 0));

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include "../stdio-common/_itoa.h" #include <stdio-common/_itoa.h>
/* Variable to synchronize work. */ /* Variable to synchronize work. */
char *__getopt_nonoption_flags; char *__getopt_nonoption_flags;
@ -40,13 +40,13 @@ extern pid_t __libc_pid;
application it does not exist anymore since it was saved for the use application it does not exist anymore since it was saved for the use
in getopt. */ in getopt. */
void void
__getopt_clean_environment (void) __getopt_clean_environment (char **env)
{ {
/* Bash 2.0 puts a special variable in the environment for each /* Bash 2.0 puts a special variable in the environment for each
command it runs, specifying which ARGV elements are the results command it runs, specifying which ARGV elements are the results
of file name wildcard expansion and therefore should not be of file name wildcard expansion and therefore should not be
considered as options. */ considered as options. */
static const char envvar_tail[] = "_GNU_nonoption_argv_flags_"; static const char envvar_tail[] = "_GNU_nonoption_argv_flags_=";
char var[100]; char var[100];
char *cp, **ep; char *cp, **ep;
size_t len; size_t len;
@ -56,19 +56,19 @@ __getopt_clean_environment (void)
if (__libc_pid == 0) if (__libc_pid == 0)
__libc_pid = getpid (); __libc_pid = getpid ();
/* Construct "_<PID>_GNU_nonoption_argv_flags_" string. */ /* Construct "_<PID>_GNU_nonoption_argv_flags_=" string. */
cp = memcpy (&var[sizeof (var) - sizeof (envvar_tail)], envvar_tail, cp = memcpy (&var[sizeof (var) - sizeof (envvar_tail)], envvar_tail,
sizeof (envvar_tail)); sizeof (envvar_tail));
cp = _itoa_word (__libc_pid, cp, 10, 0); cp = _itoa_word (__libc_pid, cp, 10, 0);
*--cp = '_'; *--cp = '_';
len = (var + sizeof (var) - 1) - cp; len = (var + sizeof (var) - 1) - cp;
for (ep = __environ; *ep != NULL; ++ep) for (ep = env; *ep != NULL; ++ep)
if (!strncmp (*ep, cp, len) && (*ep)[len] == '=') if (!strncmp (*ep, cp, len))
{ {
/* Found it. Store this pointer and move later ones back. */ /* Found it. Store this pointer and move later ones back. */
char **dp = ep; char **dp = ep;
__getopt_nonoption_flags = &(*ep)[len + 1]; __getopt_nonoption_flags = &(*ep)[len];
do do
dp[0] = dp[1]; dp[0] = dp[1];
while (*dp++); while (*dp++);

View File

@ -252,6 +252,11 @@ extern char *alloca ();
#undef GLOB_PERIOD #undef GLOB_PERIOD
#include <glob.h> #include <glob.h>
static
#if __GNUC__ - 0 >= 2
inline
#endif
const char *next_brace_sub __P ((const char *begin));
static int glob_in_dir __P ((const char *pattern, const char *directory, static int glob_in_dir __P ((const char *pattern, const char *directory,
int flags, int flags,
int (*errfunc) __P ((const char *, int)), int (*errfunc) __P ((const char *, int)),

View File

@ -34,10 +34,12 @@ extern char **_dl_argv;
extern char **_environ; extern char **_environ;
extern size_t _dl_pagesize; extern size_t _dl_pagesize;
extern const char *_dl_platform; extern const char *_dl_platform;
extern unsigned long _dl_hwcap;
extern size_t _dl_platformlen; extern size_t _dl_platformlen;
extern void _end; extern void _end;
extern void ENTRY_POINT (void); extern void ENTRY_POINT (void);
ElfW(Addr) _dl_base_addr;
int __libc_enable_secure; int __libc_enable_secure;
int __libc_multiple_libcs; /* Defining this here avoids the inclusion int __libc_multiple_libcs; /* Defining this here avoids the inclusion
of init-first. */ of init-first. */
@ -87,6 +89,9 @@ _dl_sysdep_start (void **start_argptr,
case AT_ENTRY: case AT_ENTRY:
user_entry = av->a_un.a_val; user_entry = av->a_un.a_val;
break; break;
case AT_BASE:
_dl_base_addr = av->a_un.a_val;
break;
case AT_UID: case AT_UID:
uid = av->a_un.a_val; uid = av->a_un.a_val;
break; break;
@ -103,7 +108,7 @@ _dl_sysdep_start (void **start_argptr,
_dl_platform = av->a_un.a_ptr; _dl_platform = av->a_un.a_ptr;
break; break;
case AT_HWCAP: case AT_HWCAP:
/* Well, what shall we use? A string or an integer with bits? */ _dl_hwcap = av->a_un.a_val;
break; break;
} }
@ -187,6 +192,12 @@ _dl_show_auxv (void)
16, 0), 16, 0),
"\n", NULL); "\n", NULL);
break; break;
case AT_BASE:
_dl_sysdep_message ("AT_BASE: 0x",
_itoa_word (av->a_un.a_val, buf + sizeof buf - 1,
16, 0),
"\n", NULL);
break;
case AT_UID: case AT_UID:
_dl_sysdep_message ("AT_UID: ", _dl_sysdep_message ("AT_UID: ",
_itoa_word (av->a_un.a_val, buf + sizeof buf - 1, _itoa_word (av->a_un.a_val, buf + sizeof buf - 1,
@ -215,10 +226,9 @@ _dl_show_auxv (void)
_dl_sysdep_message ("AT_PLATFORM: ", av->a_un.a_ptr, NULL); _dl_sysdep_message ("AT_PLATFORM: ", av->a_un.a_ptr, NULL);
break; break;
case AT_HWCAP: case AT_HWCAP:
/* Well, what shall we use? A string or an integer with bits? */
_dl_sysdep_message ("AT_HWCAP: ", _dl_sysdep_message ("AT_HWCAP: ",
_itoa_word (av->a_un.a_val, buf + sizeof buf - 1, _itoa_word (av->a_un.a_val, buf + sizeof buf - 1,
10, 0), 16, 0),
"\n", NULL); "\n", NULL);
break; break;
} }

View File

@ -57,20 +57,12 @@ static inline Elf32_Addr __attribute__ ((unused))
elf_machine_load_address (void) elf_machine_load_address (void)
{ {
Elf32_Addr addr; Elf32_Addr addr;
asm (" call .Lhere\n" asm (" call 1f\n"
".Lhere: popl %0\n" "1: popl %0\n"
" subl $.Lhere, %0" " subl 1b@GOT(%%ebx), %0"
: "=r" (addr)); : "=r" (addr));
return addr; return addr;
} }
/* The `subl' insn above will contain an R_386_32 relocation entry
intended to insert the run-time address of the label `.Lhere'.
This will be the first relocation in the text of the dynamic linker;
we skip it to avoid trying to modify read-only text in this early stage. */
#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
++(const Elf32_Rel *) (dynamic_info)[DT_REL]->d_un.d_ptr; \
(dynamic_info)[DT_RELSZ]->d_un.d_val -= sizeof (Elf32_Rel);
#ifndef PROF #ifndef PROF
/* We add a declaration of this function here so that in dl-runtime.c /* We add a declaration of this function here so that in dl-runtime.c
@ -132,6 +124,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\ # define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
.globl _dl_runtime_resolve .globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function .type _dl_runtime_resolve, @function
.align 16
_dl_runtime_resolve: _dl_runtime_resolve:
pushl %eax # Preserve registers otherwise clobbered. pushl %eax # Preserve registers otherwise clobbered.
pushl %ecx pushl %ecx
@ -147,6 +140,7 @@ _dl_runtime_resolve:
.globl _dl_runtime_profile .globl _dl_runtime_profile
.type _dl_runtime_profile, @function .type _dl_runtime_profile, @function
.align 16
_dl_runtime_profile: _dl_runtime_profile:
pushl %eax # Preserve registers otherwise clobbered. pushl %eax # Preserve registers otherwise clobbered.
pushl %ecx pushl %ecx
@ -167,6 +161,7 @@ _dl_runtime_profile:
.globl _dl_runtime_profile .globl _dl_runtime_profile
.type _dl_runtime_resolve, @function .type _dl_runtime_resolve, @function
.type _dl_runtime_profile, @function .type _dl_runtime_profile, @function
.align 16
_dl_runtime_resolve: _dl_runtime_resolve:
_dl_runtime_profile: _dl_runtime_profile:
pushl %eax # Preserve registers otherwise clobbered. pushl %eax # Preserve registers otherwise clobbered.

View File

@ -73,6 +73,10 @@
#ifdef __GNUC__ #ifdef __GNUC__
#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__ #if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
/* The gcc, version 2.7 or below, has problems with all this inlining
code. So disable it for this version of the compiler. */
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 7)
#ifdef __cplusplus #ifdef __cplusplus
# define __MATH_INLINE __inline # define __MATH_INLINE __inline
#else #else
@ -154,6 +158,80 @@
} }
/* Miscellaneous functions */
__inline_mathcode (__sgn, __x, \
return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0))
__inline_mathcode (__pow2, __x, \
register long double __value; \
register long double __exponent; \
long int __p = (long int) __x; \
if (__x == (long double) __p) \
{ \
__asm __volatile__ \
("fscale" \
: "=t" (__value) : "0" (1.0), "u" (__x)); \
return __value; \
} \
__asm __volatile__ \
("fldl %%st(0)\n\t" \
"frndint # int(x)\n\t" \
"fxch\n\t" \
"fsub %%st(1) # fract(x)\n\t" \
"f2xm1 # 2^(fract(x)) - 1\n\t" \
: "=t" (__value), "=u" (__exponent) : "0" (__x)); \
__value += 1.0; \
__asm __volatile__ \
("fscale" \
: "=t" (__value) : "0" (__value), "u" (__exponent)); \
return __value)
#define __sincos_code \
register long double __cosr; \
register long double __sinr; \
__asm __volatile__ \
("fsincos\n\t" \
"fnstsw %%ax\n\t" \
"testl $0x400, %%eax\n\t" \
"jz 1f\n\t" \
"fldpi\n\t" \
"fadd %%st(0)\n\t" \
"fxch %%st(1)\n\t" \
"2: fprem1\n\t" \
"fnstsw %%ax\n\t" \
"testl $0x400, %%eax\n\t" \
"jnz 2b\n\t" \
"fstp %%st(1)\n\t" \
"fsincos\n\t" \
"1:" \
: "=t" (__cosr), "=u" (__sinr) : "0" (__x)); \
*__sinx = __sinr; \
*__cosx = __cosr
__MATH_INLINE void __sincos (double __x, double *__sinx, double *__cosx);
__MATH_INLINE void
__sincos (double __x, double *__sinx, double *__cosx)
{
__sincos_code;
}
__MATH_INLINE void __sincosf (float __x, float *__sinx, float *__cosx);
__MATH_INLINE void
__sincosf (float __x, float *__sinx, float *__cosx)
{
__sincos_code;
}
__MATH_INLINE void __sincosl (long double __x, long double *__sinx,
long double *__cosx);
__MATH_INLINE void
__sincosl (long double __x, long double *__sinx, long double *__cosx)
{
__sincos_code;
}
/* Optimized inline implementation, sometimes with reduced precision /* Optimized inline implementation, sometimes with reduced precision
and/or argument range. */ and/or argument range. */
@ -278,10 +356,10 @@ __inline_mathop (sqrt, "fsqrt")
__inline_mathop_ (long double, __sqrtl, "fsqrt") __inline_mathop_ (long double, __sqrtl, "fsqrt")
#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 8) #if defined __GNUC__ && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 8)
__inline_mathcode_ (fabs, __x, return __builtin_fabs (__x)) __inline_mathcode_ (double, fabs, __x, return __builtin_fabs (__x))
__inline_mathcode_ (fabsf, __x, return __builtin_fabsf (__x)) __inline_mathcode_ (float, fabsf, __x, return __builtin_fabsf (__x))
__inline_mathcode_ (fabsl, __x, return __builtin_fabsl (__x)) __inline_mathcode_ (long double, fabsl, __x, return __builtin_fabsl (__x))
__inline_mathcode_ (__fabsl, __x, return __builtin_fabsl (__x)) __inline_mathcode_ (long double, __fabsl, __x, return __builtin_fabsl (__x))
#else #else
__inline_mathop (fabs, "fabs") __inline_mathop (fabs, "fabs")
__inline_mathop_ (long double, __fabsl, "fabs") __inline_mathop_ (long double, __fabsl, "fabs")
@ -356,7 +434,7 @@ ldexp (double __x, int __y)
/* Optimized versions for some non-standardized functions. */ /* Optimized versions for some non-standardized functions. */
#if defined __USE_ISOC9X || defined __USE_MISC #if defined __USE_ISOC9X || defined __USE_MISC
__inline_mathop_decl (log2, "fyl2x", "u" (1.0), "0" (__x) : "st(1)") __inline_mathop(log2, "fld1; fxch; fyl2x")
__inline_mathcode (expm1, __x, __expm1_code) __inline_mathcode (expm1, __x, __expm1_code)
@ -443,15 +521,12 @@ __finite (double __x)
("orl $0x800fffff, %0\n\t" ("orl $0x800fffff, %0\n\t"
"incl %0\n\t" "incl %0\n\t"
"shrl $31, %0" "shrl $31, %0"
: "=q" (__result) : "0" (((int *) &__x)[1])); : "=q" (__result) : "0" (((int *) &__x)[1]) : "cc");
return __result; return __result;
} }
/* Miscellaneous functions */ /* Miscellaneous functions */
__inline_mathcode (__sgn, __x, \
return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0))
__inline_mathcode (__coshm1, __x, \ __inline_mathcode (__coshm1, __x, \
register long double __exm1 = __expm1l (__fabsl (__x)); \ register long double __exm1 = __expm1l (__fabsl (__x)); \
return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1) return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1)
@ -459,69 +534,6 @@ __inline_mathcode (__coshm1, __x, \
__inline_mathcode (__acosh1p, __x, \ __inline_mathcode (__acosh1p, __x, \
return log1pl (__x + __sqrtl (__x) * __sqrtl (__x + 2.0))) return log1pl (__x + __sqrtl (__x) * __sqrtl (__x + 2.0)))
__inline_mathcode (__pow2, __x, \
register long double __value; \
register long double __exponent; \
long int __p = (long int) __x; \
if (__x == (long double) __p) \
return ldexpl (1.0, __p); \
__asm __volatile__ \
("fldl %%st(0)\n\t" \
"frndint # int(x)\n\t" \
"fxch\n\t" \
"fsub %%st(1) # fract(x)\n\t" \
"f2xm1 # 2^(fract(x)) - 1\n\t" \
: "=t" (__value), "=u" (__exponent) : "0" (__x)); \
__value += 1.0; \
__asm __volatile__ \
("fscale" \
: "=t" (__value) : "0" (__value), "u" (__exponent)); \
return __value)
#define __sincos_code \
register long double __cosr; \
register long double __sinr; \
__asm __volatile__ \
("fsincos\n\t" \
"fnstsw %%ax\n\t" \
"testl $0x400, %%eax\n\t" \
"jz 1f\n\t" \
"fldpi\n\t" \
"fadd %%st(0)\n\t" \
"fxch %%st(1)\n\t" \
"2: fprem1\n\t" \
"fnstsw %%ax\n\t" \
"testl $0x400, %%eax\n\t" \
"jnz 2b\n\t" \
"fstp %%st(1)\n\t" \
"fsincos\n\t" \
"1:" \
: "=t" (__cosr), "=u" (__sinr) : "0" (__x)); \
*__sinx = __sinr; \
*__cosx = __cosr
__MATH_INLINE void __sincos (double __x, double *__sinx, double *__cosx);
__MATH_INLINE void
__sincos (double __x, double *__sinx, double *__cosx)
{
__sincos_code;
}
__MATH_INLINE void __sincosf (float __x, float *__sinx, float *__cosx);
__MATH_INLINE void
__sincosf (float __x, float *__sinx, float *__cosx)
{
__sincos_code;
}
__MATH_INLINE void __sincosl (long double __x, long double *__sinx,
long double *__cosx);
__MATH_INLINE void
__sincosl (long double __x, long double *__sinx, long double *__cosx)
{
__sincos_code;
}
#endif /* __USE_MISC */ #endif /* __USE_MISC */
/* Undefine some of the large macros which are not used anymore. */ /* Undefine some of the large macros which are not used anymore. */
@ -530,6 +542,7 @@ __sincosl (long double __x, long double *__sinx, long double *__cosx)
#undef __atan2_code #undef __atan2_code
#undef __sincos_code #undef __sincos_code
#endif /* Not gcc <= 2.7. */
#endif /* __NO_MATH_INLINES */ #endif /* __NO_MATH_INLINES */
#endif /* __GNUC__ */ #endif /* __GNUC__ */

View File

@ -34,7 +34,7 @@ feraiseexcept (int excepts)
{ {
/* One example of a invalid operation is 0.0 / 0.0. */ /* One example of a invalid operation is 0.0 / 0.0. */
double d; double d;
__asm__ ("fldz; fdiv %%st, %%st(0); fwait" : "=t" (d)); __asm__ __volatile__ ("fldz; fdiv %%st, %%st(0); fwait" : "=t" (d));
(void) &d; (void) &d;
} }
@ -42,7 +42,8 @@ feraiseexcept (int excepts)
if ((FE_DIVBYZERO & excepts) != 0) if ((FE_DIVBYZERO & excepts) != 0)
{ {
double d; double d;
__asm__ ("fldz; fld1; fdivp %%st, %%st(1); fwait" : "=t" (d)); __asm__ __volatile__ ("fldz; fld1; fdivp %%st, %%st(1); fwait"
: "=t" (d));
(void) &d; (void) &d;
} }
@ -55,16 +56,16 @@ feraiseexcept (int excepts)
/* Bah, we have to clear selected exceptions. Since there is no /* Bah, we have to clear selected exceptions. Since there is no
`fldsw' instruction we have to do it the hard way. */ `fldsw' instruction we have to do it the hard way. */
__asm__ ("fnstenv %0" : "=m" (*&temp)); __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
/* Set the relevant bits. */ /* Set the relevant bits. */
temp.status_word |= FE_OVERFLOW; temp.status_word |= FE_OVERFLOW;
/* Put the new data in effect. */ /* Put the new data in effect. */
__asm__ ("fldenv %0" : : "m" (*&temp)); __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
/* And raise the exception. */ /* And raise the exception. */
__asm__ ("fwait"); __asm__ __volatile__ ("fwait");
} }
/* Next: underflow. */ /* Next: underflow. */
@ -76,16 +77,16 @@ feraiseexcept (int excepts)
/* Bah, we have to clear selected exceptions. Since there is no /* Bah, we have to clear selected exceptions. Since there is no
`fldsw' instruction we have to do it the hard way. */ `fldsw' instruction we have to do it the hard way. */
__asm__ ("fnstenv %0" : "=m" (*&temp)); __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
/* Set the relevant bits. */ /* Set the relevant bits. */
temp.status_word |= FE_UNDERFLOW; temp.status_word |= FE_UNDERFLOW;
/* Put the new data in effect. */ /* Put the new data in effect. */
__asm__ ("fldenv %0" : : "m" (*&temp)); __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
/* And raise the exception. */ /* And raise the exception. */
__asm__ ("fwait"); __asm__ __volatile__ ("fwait");
} }
/* Last: inexact. */ /* Last: inexact. */
@ -97,15 +98,15 @@ feraiseexcept (int excepts)
/* Bah, we have to clear selected exceptions. Since there is no /* Bah, we have to clear selected exceptions. Since there is no
`fldsw' instruction we have to do it the hard way. */ `fldsw' instruction we have to do it the hard way. */
__asm__ ("fnstenv %0" : "=m" (*&temp)); __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
/* Set the relevant bits. */ /* Set the relevant bits. */
temp.status_word |= FE_INEXACT; temp.status_word |= FE_INEXACT;
/* Put the new data in effect. */ /* Put the new data in effect. */
__asm__ ("fldenv %0" : : "m" (*&temp)); __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
/* And raise the exception. */ /* And raise the exception. */
__asm__ ("fwait"); __asm__ __volatile__ ("fwait");
} }
} }

View File

@ -346,7 +346,7 @@ static ElfW(Addr) _dl_preferred_address = 1
/* We require the address of the PLT entry returned from fixup, not /* We require the address of the PLT entry returned from fixup, not
the first word of the PLT entry. */ the first word of the PLT entry. */
#define ELF_FIXUP_RETURNS_ADDRESS 1 #define ELF_FIXUP_RETURN_VALUE(map, result) (&(result))
/* Nonzero iff TYPE should not be allowed to resolve to one of /* Nonzero iff TYPE should not be allowed to resolve to one of
the main executable's symbols, as for a COPY reloc. */ the main executable's symbols, as for a COPY reloc. */

View File

@ -1,4 +0,0 @@
# Local configure fragment for sysdeps/sparc.
# The assembler on SPARC needs the -fPIC flag even when it's assembler code.
ASFLAGS_SO=-fPIC

View File

@ -1,6 +0,0 @@
sinclude(./aclocal.m4)dnl Autoconf lossage
GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
# Local configure fragment for sysdeps/sparc.
# The assembler on SPARC needs the -fPIC flag even when it's assembler code.
ASFLAGS_SO=-fPIC

View File

@ -62,3 +62,7 @@ typedef double double_t;
#define INFINITY HUGE_VAL #define INFINITY HUGE_VAL
#endif #endif
/* The values returned by `ilogb' for 0 and NaN respectively. */
#define FP_ILOGB0 0x80000001
#define FP_ILOGBNAN 0x7fffffff

View File

@ -20,14 +20,16 @@
#include <fenv.h> #include <fenv.h>
#include <math.h> #include <math.h>
static void
ignore_me(double foo)
{
}
void void
feraiseexcept (int excepts) feraiseexcept (int excepts)
{ {
static volatile double sink;
static const struct {
double zero, one, max, min, sixteen, pi;
} c = {
0.0, 1.0, DBL_MAX, DBL_MIN, 16.0, M_PI
};
/* Raise exceptions represented by EXPECTS. But we must raise only /* Raise exceptions represented by EXPECTS. But we must raise only
one signal at a time. It is important the if the overflow/underflow one signal at a time. It is important the if the overflow/underflow
exception and the inexact exception are given at the same time, exception and the inexact exception are given at the same time,
@ -37,30 +39,30 @@ feraiseexcept (int excepts)
if ((FE_INVALID & excepts) != 0) if ((FE_INVALID & excepts) != 0)
{ {
/* One example of a invalid operation is 0/0. */ /* One example of a invalid operation is 0/0. */
ignore_me (0.0 / 0.0); sink = c.zero / c.zero;
} }
/* Next: division by zero. */ /* Next: division by zero. */
if ((FE_DIVBYZERO & excepts) != 0) if ((FE_DIVBYZERO & excepts) != 0)
{ {
ignore_me (1.0 / 0.0); sink = c.one / c.zero;
} }
/* Next: overflow. */ /* Next: overflow. */
if ((FE_OVERFLOW & excepts) != 0) if ((FE_OVERFLOW & excepts) != 0)
{ {
ignore_me (LDBL_MAX * LDBL_MAX); sink = c.max * c.max;
} }
/* Next: underflow. */ /* Next: underflow. */
if ((FE_UNDERFLOW & excepts) != 0) if ((FE_UNDERFLOW & excepts) != 0)
{ {
ignore_me (LDBL_MIN / 16.0); sink = c.min / c.sixteen;
} }
/* Last: inexact. */ /* Last: inexact. */
if ((FE_INEXACT & excepts) != 0) if ((FE_INEXACT & excepts) != 0)
{ {
ignore_me (1.0 / M_PI); sink = c.one / c.pi;
} }
} }

View File

@ -37,7 +37,7 @@ divrem := sdiv udiv rem urem
+divrem-S-rem := true +divrem-S-rem := true
+divrem-S-udiv := false +divrem-S-udiv := false
+divrem-S-urem := false +divrem-S-urem := false
$(divrem:%=$(sysdep_dir)/sparc/%.S): $(sysdep_dir)/sparc/divrem.m4 $(divrem:%=$(sysdep_dir)/sparc/sparc32/%.S): $(sysdep_dir)/sparc/sparc32/divrem.m4
(echo "define(NAME,\`.$(+divrem-NAME)')\ (echo "define(NAME,\`.$(+divrem-NAME)')\
define(OP,\`$(+divrem-OP-$(+divrem-NAME))')\ define(OP,\`$(+divrem-OP-$(+divrem-NAME))')\
define(S,\`$(+divrem-S-$(+divrem-NAME))')\ define(S,\`$(+divrem-S-$(+divrem-NAME))')\
@ -48,4 +48,4 @@ $(divrem:%=$(sysdep_dir)/sparc/%.S): $(sysdep_dir)/sparc/divrem.m4
mv -f $@-tmp $@ mv -f $@-tmp $@
test ! -d CVS || cvs commit -m'Regenerated from $<' $@ test ! -d CVS || cvs commit -m'Regenerated from $<' $@
sysdep-realclean := $(sysdep-realclean) $(divrem:%=sysdeps/sparc/%.S) sysdep-realclean := $(sysdep-realclean) $(divrem:%=sysdeps/sparc/sparc32/%.S)

View File

@ -22,38 +22,43 @@
#include <bits/setjmp.h> #include <bits/setjmp.h>
#define ENV(reg) [%g1 + (reg * 4)] #define ENV(reg) [%g1 + (reg * 4)]
ENTRY (__longjmp) ENTRY(__longjmp)
/* Store our arguments in global registers so we can still /* Store our arguments in global registers so we can still
use them while unwinding frames and their register windows. */ use them while unwinding frames and their register windows. */
mov %o0, %g1 /* ENV in %g1 */ mov %o0, %g1 /* ENV in %g1 */
orcc %o1, %g0, %g6 /* VAL in %g6 */ orcc %o1, %g0, %g2 /* VAL in %g2 */
be,a 0f /* Branch if zero; else skip delay slot. */ be,a 0f /* Branch if zero; else skip delay slot. */
mov 1, %g6 /* Delay slot only hit if zero: VAL = 1. */ mov 1, %g2 /* Delay slot only hit if zero: VAL = 1. */
0: 0:
/* Cache target FP in register %g3. */
/* Cache target FP in register %g7. */ ld ENV(JB_FP), %g3
ld ENV (JB_FP), %g7
/* Now we will loop, unwinding the register windows up the stack /* Now we will loop, unwinding the register windows up the stack
until the restored %fp value matches the target value in %g7. */ until the restored %fp value matches the target value in %g3. */
loop: cmp %fp, %g7 /* Have we reached the target frame? */ LOC(loop):
bl,a loop /* Loop while current fp is below target. */ cmp %fp, %g3 /* Have we reached the target frame? */
bl,a LOC(loop) /* Loop while current fp is below target. */
restore /* Unwind register window in delay slot. */ restore /* Unwind register window in delay slot. */
be,a found /* Better have hit it exactly. */ be,a LOC(found) /* Better have hit it exactly. */
ld ENV (JB_SP), %o0 /* Delay slot: extract target SP. */ ld ENV(JB_SP), %o0 /* Delay slot: extract target SP. */
bogus: /* Get here only if the jmp_buf or stack is clobbered. */ LOC(bogus):
call C_SYMBOL_NAME (abort) /* Get here only if the jmp_buf or stack is clobbered. */
nop call C_SYMBOL_NAME(abort)
nop
unimp 0 unimp 0
found: /* We have unwound register windows so %fp matches the target. */ LOC(found):
/* We have unwound register windows so %fp matches the target. */
cmp %o0, %sp /* Check jmp_buf SP vs register window. */ cmp %o0, %sp /* Check jmp_buf SP vs register window. */
bge,a sp_ok /* Saved must not be deeper than register. */ bge,a LOC(sp_ok) /* Saved must not be deeper than register. */
mov %o0, %sp /* OK, install new SP. */ mov %o0, %sp /* OK, install new SP. */
b,a bogus /* Bogus, we lose. */ b,a LOC(bogus) /* Bogus, we lose. */
sp_ok: ld ENV (JB_PC), %o0 /* Extract target return PC. */ LOC(sp_ok):
ld ENV(JB_PC), %o0 /* Extract target return PC. */
jmp %o0 + 8 /* Return there. */ jmp %o0 + 8 /* Return there. */
mov %g6, %o0 /* Delay slot: set return value. */ mov %g2, %o0 /* Delay slot: set return value. */
END(__longjmp)

View File

@ -1,20 +1,20 @@
! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store ! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
! sum in a third limb vector. ! sum in a third limb vector.
!
! Copyright (C) 1995, 1996 Free Software Foundation, Inc. ! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library. ! This file is part of the GNU MP Library.
!
! The GNU MP Library is free software; you can redistribute it and/or modify ! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by ! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your ! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version. ! option) any later version.
!
! The GNU MP Library is distributed in the hope that it will be useful, but ! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details. ! License for more details.
!
! You should have received a copy of the GNU Library General Public License ! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to ! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,205 +22,217 @@
! INPUT PARAMETERS ! INPUT PARAMETERS
#define res_ptr %o0 #define RES_PTR %o0
#define s1_ptr %o1 #define S1_PTR %o1
#define s2_ptr %o2 #define S2_PTR %o2
#define size %o3 #define SIZE %o3
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_add_n)
.align 4 xor S2_PTR,RES_PTR,%g1
.global C_SYMBOL_NAME(__mpn_add_n)
C_SYMBOL_NAME(__mpn_add_n):
xor s2_ptr,res_ptr,%g1
andcc %g1,4,%g0 andcc %g1,4,%g0
bne L1 ! branch if alignment differs bne LOC(1) ! branch if alignment differs
nop nop
! ** V1a ** ! ** V1a **
L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0 LOC(0): andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
be L_v1 ! if no, branch be LOC(v1) ! if no, branch
nop nop
/* Add least significant limb separately to align res_ptr and s2_ptr */ /* Add least significant limb separately to align RES_PTR and S2_PTR */
ld [s1_ptr],%g4 ld [S1_PTR],%g4
add s1_ptr,4,s1_ptr add S1_PTR,4,S1_PTR
ld [s2_ptr],%g2 ld [S2_PTR],%g2
add s2_ptr,4,s2_ptr add S2_PTR,4,S2_PTR
add size,-1,size add SIZE,-1,SIZE
addcc %g4,%g2,%o4 addcc %g4,%g2,%o4
st %o4,[res_ptr] st %o4,[RES_PTR]
add res_ptr,4,res_ptr add RES_PTR,4,RES_PTR
L_v1: addx %g0,%g0,%o4 ! save cy in register LOC(v1):
cmp size,2 ! if size < 2 ... addx %g0,%g0,%o4 ! save cy in register
bl Lend2 ! ... branch to tail code cmp SIZE,2 ! if SIZE < 2 ...
bl LOC(end2) ! ... branch to tail code
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
ld [s1_ptr+0],%g4 ld [S1_PTR+0],%g4
addcc size,-10,size addcc SIZE,-10,SIZE
ld [s1_ptr+4],%g1 ld [S1_PTR+4],%g1
ldd [s2_ptr+0],%g2 ldd [S2_PTR+0],%g2
blt Lfin1 blt LOC(fin1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */ /* Add blocks of 8 limbs until less than 8 limbs remain */
Loop1: addxcc %g4,%g2,%o4 LOC(loop1):
ld [s1_ptr+8],%g4
addxcc %g1,%g3,%o5
ld [s1_ptr+12],%g1
ldd [s2_ptr+8],%g2
std %o4,[res_ptr+0]
addxcc %g4,%g2,%o4 addxcc %g4,%g2,%o4
ld [s1_ptr+16],%g4 ld [S1_PTR+8],%g4
addxcc %g1,%g3,%o5 addxcc %g1,%g3,%o5
ld [s1_ptr+20],%g1 ld [S1_PTR+12],%g1
ldd [s2_ptr+16],%g2 ldd [S2_PTR+8],%g2
std %o4,[res_ptr+8] std %o4,[RES_PTR+0]
addxcc %g4,%g2,%o4 addxcc %g4,%g2,%o4
ld [s1_ptr+24],%g4 ld [S1_PTR+16],%g4
addxcc %g1,%g3,%o5 addxcc %g1,%g3,%o5
ld [s1_ptr+28],%g1 ld [S1_PTR+20],%g1
ldd [s2_ptr+24],%g2 ldd [S2_PTR+16],%g2
std %o4,[res_ptr+16] std %o4,[RES_PTR+8]
addxcc %g4,%g2,%o4 addxcc %g4,%g2,%o4
ld [s1_ptr+32],%g4 ld [S1_PTR+24],%g4
addxcc %g1,%g3,%o5 addxcc %g1,%g3,%o5
ld [s1_ptr+36],%g1 ld [S1_PTR+28],%g1
ldd [s2_ptr+32],%g2 ldd [S2_PTR+24],%g2
std %o4,[res_ptr+24] std %o4,[RES_PTR+16]
addxcc %g4,%g2,%o4
ld [S1_PTR+32],%g4
addxcc %g1,%g3,%o5
ld [S1_PTR+36],%g1
ldd [S2_PTR+32],%g2
std %o4,[RES_PTR+24]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-8,size addcc SIZE,-8,SIZE
add s1_ptr,32,s1_ptr add S1_PTR,32,S1_PTR
add s2_ptr,32,s2_ptr add S2_PTR,32,S2_PTR
add res_ptr,32,res_ptr add RES_PTR,32,RES_PTR
bge Loop1 bge LOC(loop1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lfin1: addcc size,8-2,size LOC(fin1):
blt Lend1 addcc SIZE,8-2,SIZE
blt LOC(end1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 2 limbs until less than 2 limbs remain */ /* Add blocks of 2 limbs until less than 2 limbs remain */
Loope1: addxcc %g4,%g2,%o4 LOC(loope1):
ld [s1_ptr+8],%g4 addxcc %g4,%g2,%o4
ld [S1_PTR+8],%g4
addxcc %g1,%g3,%o5 addxcc %g1,%g3,%o5
ld [s1_ptr+12],%g1 ld [S1_PTR+12],%g1
ldd [s2_ptr+8],%g2 ldd [S2_PTR+8],%g2
std %o4,[res_ptr+0] std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size addcc SIZE,-2,SIZE
add s1_ptr,8,s1_ptr add S1_PTR,8,S1_PTR
add s2_ptr,8,s2_ptr add S2_PTR,8,S2_PTR
add res_ptr,8,res_ptr add RES_PTR,8,RES_PTR
bge Loope1 bge LOC(loope1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lend1: addxcc %g4,%g2,%o4 LOC(end1):
addxcc %g4,%g2,%o4
addxcc %g1,%g3,%o5 addxcc %g1,%g3,%o5
std %o4,[res_ptr+0] std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
andcc size,1,%g0 andcc SIZE,1,%g0
be Lret1 be LOC(ret1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */ /* Add last limb */
ld [s1_ptr+8],%g4 ld [S1_PTR+8],%g4
ld [s2_ptr+8],%g2 ld [S2_PTR+8],%g2
addxcc %g4,%g2,%o4 addxcc %g4,%g2,%o4
st %o4,[res_ptr+8] st %o4,[RES_PTR+8]
Lret1: retl LOC(ret1):
retl
addx %g0,%g0,%o0 ! return carry-out from most sign. limb addx %g0,%g0,%o0 ! return carry-out from most sign. limb
L1: xor s1_ptr,res_ptr,%g1 LOC(1): xor S1_PTR,RES_PTR,%g1
andcc %g1,4,%g0 andcc %g1,4,%g0
bne L2 bne LOC(2)
nop nop
! ** V1b ** ! ** V1b **
mov s2_ptr,%g1 mov S2_PTR,%g1
mov s1_ptr,s2_ptr mov S1_PTR,S2_PTR
b L0 b LOC(0)
mov %g1,s1_ptr mov %g1,S1_PTR
! ** V2 ** ! ** V2 **
/* If we come here, the alignment of s1_ptr and res_ptr as well as the /* If we come here, the alignment of S1_PTR and RES_PTR as well as the
alignment of s2_ptr and res_ptr differ. Since there are only two ways alignment of S2_PTR and RES_PTR differ. Since there are only two ways
things can be aligned (that we care about) we now know that the alignment things can be aligned (that we care about) we now know that the alignment
of s1_ptr and s2_ptr are the same. */ of S1_PTR and S2_PTR are the same. */
L2: cmp size,1 LOC(2): cmp SIZE,1
be Ljone be LOC(jone)
nop nop
andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0 andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
be L_v2 ! if no, branch be LOC(v2) ! if no, branch
nop nop
/* Add least significant limb separately to align s1_ptr and s2_ptr */ /* Add least significant limb separately to align S1_PTR and S2_PTR */
ld [s1_ptr],%g4 ld [S1_PTR],%g4
add s1_ptr,4,s1_ptr add S1_PTR,4,S1_PTR
ld [s2_ptr],%g2 ld [S2_PTR],%g2
add s2_ptr,4,s2_ptr add S2_PTR,4,S2_PTR
add size,-1,size add SIZE,-1,SIZE
addcc %g4,%g2,%o4 addcc %g4,%g2,%o4
st %o4,[res_ptr] st %o4,[RES_PTR]
add res_ptr,4,res_ptr add RES_PTR,4,RES_PTR
L_v2: addx %g0,%g0,%o4 ! save cy in register LOC(v2):
addcc size,-8,size addx %g0,%g0,%o4 ! save cy in register
blt Lfin2 addcc SIZE,-8,SIZE
blt LOC(fin2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */ /* Add blocks of 8 limbs until less than 8 limbs remain */
Loop2: ldd [s1_ptr+0],%g2 LOC(loop2):
ldd [s2_ptr+0],%o4 ldd [S1_PTR+0],%g2
ldd [S2_PTR+0],%o4
addxcc %g2,%o4,%g2 addxcc %g2,%o4,%g2
st %g2,[res_ptr+0] st %g2,[RES_PTR+0]
addxcc %g3,%o5,%g3 addxcc %g3,%o5,%g3
st %g3,[res_ptr+4] st %g3,[RES_PTR+4]
ldd [s1_ptr+8],%g2 ldd [S1_PTR+8],%g2
ldd [s2_ptr+8],%o4 ldd [S2_PTR+8],%o4
addxcc %g2,%o4,%g2 addxcc %g2,%o4,%g2
st %g2,[res_ptr+8] st %g2,[RES_PTR+8]
addxcc %g3,%o5,%g3 addxcc %g3,%o5,%g3
st %g3,[res_ptr+12] st %g3,[RES_PTR+12]
ldd [s1_ptr+16],%g2 ldd [S1_PTR+16],%g2
ldd [s2_ptr+16],%o4 ldd [S2_PTR+16],%o4
addxcc %g2,%o4,%g2 addxcc %g2,%o4,%g2
st %g2,[res_ptr+16] st %g2,[RES_PTR+16]
addxcc %g3,%o5,%g3 addxcc %g3,%o5,%g3
st %g3,[res_ptr+20] st %g3,[RES_PTR+20]
ldd [s1_ptr+24],%g2 ldd [S1_PTR+24],%g2
ldd [s2_ptr+24],%o4 ldd [S2_PTR+24],%o4
addxcc %g2,%o4,%g2 addxcc %g2,%o4,%g2
st %g2,[res_ptr+24] st %g2,[RES_PTR+24]
addxcc %g3,%o5,%g3 addxcc %g3,%o5,%g3
st %g3,[res_ptr+28] st %g3,[RES_PTR+28]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-8,size addcc SIZE,-8,SIZE
add s1_ptr,32,s1_ptr add S1_PTR,32,S1_PTR
add s2_ptr,32,s2_ptr add S2_PTR,32,S2_PTR
add res_ptr,32,res_ptr add RES_PTR,32,RES_PTR
bge Loop2 bge LOC(loop2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lfin2: addcc size,8-2,size LOC(fin2):
blt Lend2 addcc SIZE,8-2,SIZE
blt LOC(end2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Loope2: ldd [s1_ptr+0],%g2 LOC(loope2):
ldd [s2_ptr+0],%o4 ldd [S1_PTR+0],%g2
ldd [S2_PTR+0],%o4
addxcc %g2,%o4,%g2 addxcc %g2,%o4,%g2
st %g2,[res_ptr+0] st %g2,[RES_PTR+0]
addxcc %g3,%o5,%g3 addxcc %g3,%o5,%g3
st %g3,[res_ptr+4] st %g3,[RES_PTR+4]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size addcc SIZE,-2,SIZE
add s1_ptr,8,s1_ptr add S1_PTR,8,S1_PTR
add s2_ptr,8,s2_ptr add S2_PTR,8,S2_PTR
add res_ptr,8,res_ptr add RES_PTR,8,RES_PTR
bge Loope2 bge LOC(loope2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lend2: andcc size,1,%g0 LOC(end2):
be Lret2 andcc SIZE,1,%g0
be LOC(ret2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */ /* Add last limb */
Ljone: ld [s1_ptr],%g4 LOC(jone):
ld [s2_ptr],%g2 ld [S1_PTR],%g4
ld [S2_PTR],%g2
addxcc %g4,%g2,%o4 addxcc %g4,%g2,%o4
st %o4,[res_ptr] st %o4,[RES_PTR]
Lret2: retl LOC(ret2):
retl
addx %g0,%g0,%o0 ! return carry-out from most sign. limb addx %g0,%g0,%o0 ! return carry-out from most sign. limb
END(__mpn_add_n)

View File

@ -1,20 +1,20 @@
! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add ! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add
! the result to a second limb vector. ! the result to a second limb vector.
!
! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. ! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library. ! This file is part of the GNU MP Library.
!
! The GNU MP Library is free software; you can redistribute it and/or modify ! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by ! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your ! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version. ! option) any later version.
!
! The GNU MP Library is distributed in the hope that it will be useful, but ! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details. ! License for more details.
!
! You should have received a copy of the GNU Library General Public License ! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to ! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,17 +22,14 @@
! INPUT PARAMETERS ! INPUT PARAMETERS
! res_ptr o0 ! RES_PTR o0
! s1_ptr o1 ! S1_PTR o1
! size o2 ! SIZE o2
! s2_limb o3 ! S2_LIMB o3
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_addmul_1)
.align 4
.global C_SYMBOL_NAME(__mpn_addmul_1)
C_SYMBOL_NAME(__mpn_addmul_1):
! Make S1_PTR and RES_PTR point at the end of their blocks ! Make S1_PTR and RES_PTR point at the end of their blocks
! and put (- 4 x SIZE) in index/loop counter. ! and put (- 4 x SIZE) in index/loop counter.
sll %o2,2,%o2 sll %o2,2,%o2
@ -41,19 +38,19 @@ C_SYMBOL_NAME(__mpn_addmul_1):
sub %g0,%o2,%o2 sub %g0,%o2,%o2
cmp %o3,0xfff cmp %o3,0xfff
bgu Large bgu LOC(large)
nop nop
ld [%o1+%o2],%o5 ld [%o1+%o2],%o5
mov 0,%o0 mov 0,%o0
b L0 b LOC(0)
add %o4,-4,%o4 add %o4,-4,%o4
Loop0: LOC(loop0):
addcc %o5,%g1,%g1 addcc %o5,%g1,%g1
ld [%o1+%o2],%o5 ld [%o1+%o2],%o5
addx %o0,%g0,%o0 addx %o0,%g0,%o0
st %g1,[%o4+%o2] st %g1,[%o4+%o2]
L0: wr %g0,%o3,%y LOC(0): wr %g0,%o3,%y
sra %o5,31,%g2 sra %o5,31,%g2
and %o3,%g2,%g2 and %o3,%g2,%g2
andcc %g1,0,%g1 andcc %g1,0,%g1
@ -79,7 +76,7 @@ L0: wr %g0,%o3,%y
addcc %g1,%o0,%g1 addcc %g1,%o0,%g1
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter addcc %o2,4,%o2 ! loop counter
bne Loop0 bne LOC(loop0)
ld [%o4+%o2],%o5 ld [%o4+%o2],%o5
addcc %o5,%g1,%g1 addcc %o5,%g1,%g1
@ -88,17 +85,18 @@ L0: wr %g0,%o3,%y
st %g1,[%o4+%o2] st %g1,[%o4+%o2]
Large: ld [%o1+%o2],%o5 LOC(large):
ld [%o1+%o2],%o5
mov 0,%o0 mov 0,%o0
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0 sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
b L1 b LOC(1)
add %o4,-4,%o4 add %o4,-4,%o4
Loop: LOC(loop):
addcc %o5,%g3,%g3 addcc %o5,%g3,%g3
ld [%o1+%o2],%o5 ld [%o1+%o2],%o5
addx %o0,%g0,%o0 addx %o0,%g0,%o0
st %g3,[%o4+%o2] st %g3,[%o4+%o2]
L1: wr %g0,%o5,%y LOC(1): wr %g0,%o5,%y
and %o5,%g4,%g2 and %o5,%g4,%g2
andcc %g0,%g0,%g1 andcc %g0,%g0,%g1
mulscc %g1,%o3,%g1 mulscc %g1,%o3,%g1
@ -138,10 +136,12 @@ L1: wr %g0,%o5,%y
addcc %g3,%o0,%g3 addcc %g3,%o0,%g3
addx %g2,%g1,%o0 addx %g2,%g1,%o0
addcc %o2,4,%o2 addcc %o2,4,%o2
bne Loop bne LOC(loop)
ld [%o4+%o2],%o5 ld [%o4+%o2],%o5
addcc %o5,%g3,%g3 addcc %o5,%g3,%g3
addx %o0,%g0,%o0 addx %o0,%g0,%o0
retl retl
st %g3,[%o4+%o2] st %g3,[%o4+%o2]
END(__mpn_addmul_1)

View File

@ -16,7 +16,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
#include "sysdep.h" #include <sysdep.h>
/* Code produced by Sun's C compiler calls this function with two extra /* Code produced by Sun's C compiler calls this function with two extra
arguments which it makes relocatable symbols but seem always to be arguments which it makes relocatable symbols but seem always to be
@ -30,3 +30,4 @@ ENTRY (__builtin_alloca)
sub %sp, %o0, %sp /* Push some stack space. */ sub %sp, %o0, %sp /* Push some stack space. */
retl /* Return; the returned buffer leaves 96 */ retl /* Return; the returned buffer leaves 96 */
add %sp, 96, %o0 /* bytes of register save area at the top. */ add %sp, 96, %o0 /* bytes of register save area at the top. */
END (__builtin_alloca)

View File

@ -1,40 +1 @@
/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. Sparc version. /* _setjmp is in setjmp.S */
Copyright (C) 1994, 1997 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 Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <sysdep.h>
ENTRY (_setjmp)
#ifdef PIC
save %sp, -64, %sp
1: call 2f
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %g1
2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %g1
add %g1, %o7, %g1
sethi %hi(C_SYMBOL_NAME(__sigsetjmp)), %g2
restore
or %g2, %lo(C_SYMBOL_NAME(__sigsetjmp)), %g2
ld [%g1+%g2], %g1
#else
sethi %hi(C_SYMBOL_NAME(__sigsetjmp)), %g1
or %g1, %lo(C_SYMBOL_NAME(__sigsetjmp)), %g1
#endif
jmp %g1
mov %g0, %o1 /* Pass second argument of zero. */

View File

@ -1,40 +1 @@
/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. Sparc version. /* setjmp is in setjmp.S */
Copyright (C) 1994, 1997 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 Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <sysdep.h>
ENTRY (setjmp)
#ifdef PIC
save %sp, -64, %sp
1: call 2f
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %g1
2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %g1
add %g1, %o7, %g1
sethi %hi(C_SYMBOL_NAME(__sigsetjmp)), %g2
restore
or %g2, %lo(C_SYMBOL_NAME(__sigsetjmp)), %g2
ld [%g1+%g2], %g1
#else
sethi %hi(C_SYMBOL_NAME(__sigsetjmp)), %g1
or %g1, %lo(C_SYMBOL_NAME(__sigsetjmp)), %g1
#endif
jmp %g1
mov 1, %o1 /* Pass second argument of one. */

View File

@ -47,8 +47,8 @@ define(V, `%o5')dnl
dnl dnl
dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d
define(T, `%g1')dnl define(T, `%g1')dnl
define(SC, `%g7')dnl define(SC, `%g2')dnl
ifelse(S, `true', `define(SIGN, `%g6')')dnl ifelse(S, `true', `define(SIGN, `%g3')')dnl
dnl dnl
dnl This is the recursive definition for developing quotient digits. dnl This is the recursive definition for developing quotient digits.
@ -65,7 +65,7 @@ dnl modified to reflect the output R.
dnl dnl
define(DEVELOP_QUOTIENT_BITS, define(DEVELOP_QUOTIENT_BITS,
` ! depth $1, accumulated bits $2 ` ! depth $1, accumulated bits $2
bl L.$1.eval(2**N+$2) bl LOC($1.eval(2**N+$2))
srl V,1,V srl V,1,V
! remainder is positive ! remainder is positive
subcc R,V,R subcc R,V,R
@ -73,7 +73,7 @@ define(DEVELOP_QUOTIENT_BITS,
` b 9f ` b 9f
add Q, ($2*2+1), Q add Q, ($2*2+1), Q
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')') ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')')
L.$1.eval(2**N+$2): LOC($1.eval(2**N+$2)):
! remainder is negative ! remainder is negative
addcc R,V,R addcc R,V,R
ifelse($1, N, ifelse($1, N,
@ -82,18 +82,10 @@ L.$1.eval(2**N+$2):
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')') ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')')
ifelse($1, 1, `9:')')dnl ifelse($1, 1, `9:')')dnl
#include "sysdep.h" #include <sysdep.h>
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sys/trap.h> #include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
FUNC(NAME) ENTRY(NAME)
ifelse(S, `true', ifelse(S, `true',
` ! compute sign of result; if neither is negative, no problem ` ! compute sign of result; if neither is negative, no problem
orcc divisor, dividend, %g0 ! either negative? orcc divisor, dividend, %g0 ! either negative?
@ -124,11 +116,11 @@ ifelse(OP, `div',
1: 1:
cmp R, V ! if divisor exceeds dividend, done cmp R, V ! if divisor exceeds dividend, done
blu Lgot_result ! (and algorithm fails otherwise) blu LOC(got_result) ! (and algorithm fails otherwise)
clr Q clr Q
sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T
cmp R, T cmp R, T
blu Lnot_really_big blu LOC(not_really_big)
clr ITER clr ITER
! `Here the dividend is >= 2**(31-N) or so. We must be careful here, ! `Here the dividend is >= 2**(31-N) or so. We must be careful here,
@ -146,7 +138,7 @@ ifelse(OP, `div',
! Now compute SC. ! Now compute SC.
2: addcc V, V, V 2: addcc V, V, V
bcc Lnot_too_big bcc LOC(not_too_big)
add SC, 1, SC add SC, 1, SC
! We get here if the divisor overflowed while shifting. ! We get here if the divisor overflowed while shifting.
@ -155,14 +147,14 @@ ifelse(OP, `div',
sll T, TOPBITS, T ! high order bit sll T, TOPBITS, T ! high order bit
srl V, 1, V ! rest of V srl V, 1, V ! rest of V
add V, T, V add V, T, V
b Ldo_single_div b LOC(do_single_div)
sub SC, 1, SC sub SC, 1, SC
Lnot_too_big: LOC(not_too_big):
3: cmp V, R 3: cmp V, R
blu 2b blu 2b
nop nop
be Ldo_single_div be LOC(do_single_div)
nop nop
/* NB: these are commented out in the V8-Sparc manual as well */ /* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */ /* (I do not understand this) */
@ -177,15 +169,15 @@ ifelse(OP, `div',
! order bit set in the first step, just falling into the regular ! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around. ! division loop will mess up the first time around.
! So we unroll slightly... ! So we unroll slightly...
Ldo_single_div: LOC(do_single_div):
subcc SC, 1, SC subcc SC, 1, SC
bl Lend_regular_divide bl LOC(end_regular_divide)
nop nop
sub R, V, R sub R, V, R
mov 1, Q mov 1, Q
b Lend_single_divloop b LOC(end_single_divloop)
nop nop
Lsingle_divloop: LOC(single_divloop):
sll Q, 1, Q sll Q, 1, Q
bl 1f bl 1f
srl V, 1, V srl V, 1, V
@ -197,37 +189,37 @@ ifelse(OP, `div',
add R, V, R add R, V, R
sub Q, 1, Q sub Q, 1, Q
2: 2:
Lend_single_divloop: LOC(end_single_divloop):
subcc SC, 1, SC subcc SC, 1, SC
bge Lsingle_divloop bge LOC(single_divloop)
tst R tst R
b,a Lend_regular_divide b,a LOC(end_regular_divide)
Lnot_really_big: LOC(not_really_big):
1: 1:
sll V, N, V sll V, N, V
cmp V, R cmp V, R
bleu 1b bleu 1b
addcc ITER, 1, ITER addcc ITER, 1, ITER
be Lgot_result be LOC(got_result)
sub ITER, 1, ITER sub ITER, 1, ITER
tst R ! set up for initial iteration tst R ! set up for initial iteration
Ldivloop: LOC(divloop):
sll Q, N, Q sll Q, N, Q
DEVELOP_QUOTIENT_BITS(1, 0) DEVELOP_QUOTIENT_BITS(1, 0)
Lend_regular_divide: LOC(end_regular_divide):
subcc ITER, 1, ITER subcc ITER, 1, ITER
bge Ldivloop bge LOC(divloop)
tst R tst R
bl,a Lgot_result bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!) ! non-restoring fixup here (one instruction only!)
ifelse(OP, `div', ifelse(OP, `div',
` sub Q, 1, Q ` sub Q, 1, Q
', ` add R, divisor, R ', ` add R, divisor, R
') ')
Lgot_result: LOC(got_result):
ifelse(S, `true', ifelse(S, `true',
` ! check to see if answer should be < 0 ` ! check to see if answer should be < 0
tst SIGN tst SIGN
@ -236,3 +228,5 @@ ifelse(S, `true',
1:') 1:')
retl retl
ifelse(OP, `div', `mov Q, %o0', `mov R, %o0') ifelse(OP, `div', `mov Q, %o0', `mov R, %o0')
END(NAME)

View File

@ -30,7 +30,7 @@
#define OPCODE_CALL 0x40000000 /* call ?; add PC-rel word address */ #define OPCODE_CALL 0x40000000 /* call ?; add PC-rel word address */
#define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */ #define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */
#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */ #define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
#define OPCODE_SAVE_SP64 0x9de3bfc0 /* save %sp, -64, %sp */ #define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
/* Return nonzero iff E_MACHINE is compatible with the running host. */ /* Return nonzero iff E_MACHINE is compatible with the running host. */
@ -55,7 +55,7 @@ elf_machine_dynamic (void)
static inline Elf32_Addr static inline Elf32_Addr
elf_machine_load_address (void) elf_machine_load_address (void)
{ {
register Elf32_Addr pc __asm("%o7"), got; register Elf32_Addr pc __asm("%o7"), pic __asm("%l7"), got;
/* Utilize the fact that a local .got entry will be partially /* Utilize the fact that a local .got entry will be partially
initialized at startup awaiting its RELATIVE fixup. */ initialized at startup awaiting its RELATIVE fixup. */
@ -64,50 +64,187 @@ elf_machine_load_address (void)
".Load_address:\n\t" ".Load_address:\n\t"
"call 1f\n\t" "call 1f\n\t"
"or %1,%%lo(.Load_address),%1\n" "or %1,%%lo(.Load_address),%1\n"
"1:\tld [%%l7+%1],%1" "1:\tld [%2+%1],%1"
: "=r"(pc), "=r"(got)); : "=r"(pc), "=r"(got) : "r"(pic));
return pc - got; return pc - got;
} }
Elf32_Addr addr; /* Set up the loaded object described by L so its unrelocated PLT
entries will jump to the on-demand fixup code in dl-runtime.c. */
asm ( static inline int
"add %%fp,0x44,%%o2\n\t" /* o2 = point to argc */ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
"ld [%%o2 - 4],%%o0\n\t" /* o0 = load argc */ {
"sll %%o0, 2, %%o0\n\t" /* o0 = argc * sizeof (int) */ Elf32_Addr *plt;
"add %%o2,%%o0,%%o2\n\t" /* o2 = skip over argv */ extern void _dl_runtime_resolve (Elf32_Word);
"add %%o2,4,%%o2\n\t" /* skip over null after argv */
/* Now %o2 is pointing to env, skip over that as well. */ if (l->l_info[DT_JMPREL] && lazy)
"1:\n\t" {
"ld [%%o2],%%o0\n\t" /* The entries for functions in the PLT have not yet been filled in.
"cmp %%o0,0\n\t" Their initial contents will arrange when called to set the high 22
"bnz 1b\n\t" bits of %g1 with an offset into the .rela.plt section and jump to
"add %%o2,4,%%o2\n\t" the beginning of the PLT. */
plt = (Elf32_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
/* Note that above, we want to advance the NULL after envp so /* The beginning of the PLT does:
we always add 4. */
/* Now, search for the AT_BASE property. */ save %sp, -64, %sp
"2:\n\t" pltpc: call _dl_runtime_resolve
"ld [%%o2],%%o0\n\t" nop
"cmp %%o0,0\n\t" .word MAP
"be,a 3f\n\t"
"or %%g0,%%g0,%0\n\t" This saves the register window containing the arguments, and the
"cmp %%o0,7\n\t" /* AT_BASE = 7 */ PC value (pltpc) implicitly saved in %o7 by the call points near the
"be,a 3f\n\t" location where we store the link_map pointer for this object. */
"ld [%%o2+4],%0\n\t"
"b 2b\n\t" plt[0] = OPCODE_SAVE_SP;
"add %%o2,8,%%o2\n\t" /* Construct PC-relative word address. */
/* At this point %0 has the load address for the interpreter */ plt[1] = OPCODE_CALL | (((Elf32_Addr) &_dl_runtime_resolve -
"3:\n\t" (Elf32_Addr) &plt[1]) >> 2);
: "=r" (addr) plt[2] = OPCODE_NOP; /* Fill call delay slot. */
: /* no inputs */ plt[3] = (Elf32_Addr) l;
: "o0", "o2"); }
return addr;
return lazy;
} }
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function
_dl_runtime_resolve:
/* Set up the arguments to fixup --
%o0 = link_map out of plt0
%o1 = offset of reloc entry */
ld [%o7 + 8], %o0
srl %g1, 10, %o1
call fixup
sub %o1, 4*12, %o1
jmp %o0
restore
.size _dl_runtime_resolve, . - _dl_runtime_resolve");
/* The address of the JMP_SLOT reloc is the .plt entry, thus we don't
dereference the reloc's addr to get the final destination. Ideally
there would be a generic way to return the value of the symbol from
elf_machine_relplt, but as it is, the address of the .plt entry is
good enough. */
#define ELF_FIXUP_RETURN_VALUE(map, result) ((Elf32_Addr) &(result))
/* Nonzero iff TYPE should not be allowed to resolve to one of
the main executable's symbols, as for a COPY reloc. */
#define elf_machine_lookup_noexec_p(type) ((type) == R_SPARC_COPY)
/* Nonzero iff TYPE describes relocation of a PLT entry, so
PLT entries should not be allowed to define the value. */
#define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_RELOC_NOPLT R_SPARC_JMP_SLOT
/* The SPARC never uses Elf32_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
#define ELF_MACHINE_PLTREL_OVERLAP 1
/* The PLT uses Elf32_Rela relocs. */
#define elf_machine_relplt elf_machine_rela
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
#define RTLD_START __asm__ ("\
.text
.globl _start
.type _start,@function
_start:
/* Allocate space for functions to drop their arguments. */
sub %sp, 6*4, %sp
/* Pass pointer to argument block to _dl_start. */
call _dl_start
add %sp, 22*4, %o0
/* FALTHRU */
.globl _dl_start_user
.type _dl_start_user,@function
_dl_start_user:
/* Load the PIC register. */
1: call 2f
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
add %l7, %o7, %l7
/* Save the user entry point address in %l0 */
mov %o0, %l0
/* See if we were run as a command with the executable file name as an
extra leading argument. If so, adjust the contents of the stack. */
sethi %hi(_dl_skip_args), %g2
or %g2, %lo(_dl_skip_args), %g2
ld [%l7+%g2], %i0
ld [%i0], %i0
tst %i0
beq 3f
nop
/* Find out how far to shift. */
ld [%sp+22*4], %i1 /* load argc */
sub %i1, %i0, %i1
sll %i0, 2, %i2
st %i1, [%sp+22*4]
add %sp, 23*4, %i1
add %i1, %i2, %i2
/* Copy down argv */
21: ld [%i2], %i3
add %i2, 4, %i2
tst %i3
st %i3, [%i1]
bne 21b
add %i1, 4, %i1
/* Copy down env */
22: ld [%i2], %i3
add %i2, 4, %i2
tst %i3
st %i3, [%i1]
bne 22b
add %i1, 4, %i1
/* Copy down auxiliary table. */
23: ld [%i2], %i3
ld [%i2+4], %i4
add %i2, 8, %i2
tst %i3
st %i3, [%i1]
st %i4, [%i1+4]
bne 23b
add %i1, 8, %i1
/* Load _dl_default_scope[2] to pass to _dl_init_next. */
3: sethi %hi(_dl_default_scope), %g1
or %g1, %lo(_dl_default_scope), %g1
ld [%l7+%g1], %l1
ld [%l1+2*4], %l1
/* Call _dl_init_next to return the address of an initializer to run. */
4: call _dl_init_next
mov %l1, %o0
tst %o0
beq 5f
nop
jmpl %o0, %o7
nop
ba,a 4b
/* Clear the startup flag. */
5: sethi %hi(_dl_starting_up), %g1
or %g1, %lo(_dl_starting_up), %g1
ld [%l7+%g1], %g1
st %g0, [%g1]
/* Pass our finalizer function to the user in %g1. */
sethi %hi(_dl_fini), %g1
or %g1, %lo(_dl_fini), %g1
ld [%l7+%g1], %g1
/* Jump to the user's entry point and deallocate the extra stack we got. */
jmp %l0
add %sp, 6*4, %sp
.size _dl_start_user,.-_dl_start_user");
#ifdef RESOLVE #ifdef RESOLVE
/* Perform the relocation specified by RELOC and SYM (which is fully resolved). /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */ MAP is the object containing the reloc. */
@ -117,7 +254,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
const Elf32_Sym *sym, const struct r_found_version *version, const Elf32_Sym *sym, const struct r_found_version *version,
Elf32_Addr *const reloc_addr) Elf32_Addr *const reloc_addr)
{ {
Elf32_Addr loadbase; extern unsigned long _dl_hwcap;
if (ELF32_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE) if (ELF32_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE)
{ {
@ -144,6 +281,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
switch (ELF32_R_TYPE (reloc->r_info)) switch (ELF32_R_TYPE (reloc->r_info))
{ {
case R_SPARC_COPY: case R_SPARC_COPY:
#ifndef RTLD_BOOTSTRAP
if (sym->st_size > refsym->st_size if (sym->st_size > refsym->st_size
|| (_dl_verbose && sym->st_size < refsym->st_size)) || (_dl_verbose && sym->st_size < refsym->st_size))
{ {
@ -159,14 +297,21 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
} }
memcpy (reloc_addr, (void *) value, MIN (sym->st_size, memcpy (reloc_addr, (void *) value, MIN (sym->st_size,
refsym->st_size)); refsym->st_size));
#endif
break; break;
case R_SPARC_GLOB_DAT: case R_SPARC_GLOB_DAT:
case R_SPARC_32: case R_SPARC_32:
*reloc_addr = value; *reloc_addr = value;
break; break;
case R_SPARC_JMP_SLOT: case R_SPARC_JMP_SLOT:
reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10); /* For thread safety, write the instructions from the bottom and
flush before we overwrite the critical "b,a". */
reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff); reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
if (1 || (_dl_hwcap & 1)) /* HWCAP_SPARC_FLUSH */
__asm __volatile ("flush %0+8" : : "r"(reloc_addr));
reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
if (1 || (_dl_hwcap & 1)) /* HWCAP_SPARC_FLUSH */
__asm __volatile ("flush %0+4" : : "r"(reloc_addr));
break; break;
case R_SPARC_8: case R_SPARC_8:
*(char *) reloc_addr = value; *(char *) reloc_addr = value;
@ -218,146 +363,3 @@ elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
} }
#endif /* RESOLVE */ #endif /* RESOLVE */
/* Nonzero iff TYPE should not be allowed to resolve to one of
the main executable's symbols, as for a COPY reloc. */
#define elf_machine_lookup_noexec_p(type) ((type) == R_SPARC_COPY)
/* Nonzero iff TYPE describes relocation of a PLT entry, so
PLT entries should not be allowed to define the value. */
#define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_RELOC_NOPLT R_SPARC_JMP_SLOT
/* The SPARC never uses Elf32_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
#define ELF_MACHINE_PLTREL_OVERLAP 1
/* Set up the loaded object described by L so its unrelocated PLT
entries will jump to the on-demand fixup code in dl-runtime.c. */
static inline int
elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
{
Elf32_Addr *plt;
extern void _dl_runtime_resolve (Elf32_Word);
if (l->l_info[DT_JMPREL] && lazy)
{
/* The entries for functions in the PLT have not yet been filled in.
Their initial contents will arrange when called to set the high 22
bits of %g1 with an offset into the .rela.plt section and jump to
the beginning of the PLT. */
plt = (Elf32_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
/* The beginning of the PLT does:
save %sp, -64, %sp
pltpc: call _dl_runtime_resolve
nop
.word MAP
This saves the register window containing the arguments, and the
PC value (pltpc) implicitly saved in %o7 by the call points near the
location where we store the link_map pointer for this object. */
plt[0] = OPCODE_SAVE_SP64; /* save %sp, -64, %sp */
/* Construct PC-relative word address. */
plt[1] = OPCODE_CALL | (((Elf32_Addr) &_dl_runtime_resolve -
(Elf32_Addr) &plt[1]) >> 2);
plt[2] = OPCODE_NOP; /* Fill call delay slot. */
plt[3] = (Elf32_Addr *) l;
}
return lazy;
}
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
# Trampoline for _dl_runtime_resolver
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function
_dl_runtime_resolve:
t 1
#call %g0
# Pass two args to fixup: the PLT address computed from the PC saved
# in the PLT's call insn, and the reloc offset passed in %g1.
#ld [%o7 + 8], %o1 | Second arg, loaded from PLTPC[2].
#call fixup
#shrl %g1, 22, %o0 | First arg, set in delay slot of call.
# Jump to the real function.
#jmpl %o0, %g0
# In the delay slot of that jump, restore the register window
# saved by the first insn of the PLT.
#restore
.size _dl_runtime_resolve, . - _dl_runtime_resolve
");
/* The PLT uses Elf32_Rela relocs. */
#define elf_machine_relplt elf_machine_rela
/* Mask identifying addresses reserved for the user program,
where the dynamic linker should not map anything. */
#define ELF_MACHINE_USER_ADDRESS_MASK ???
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
#define RTLD_START __asm__ ( \
".text\n\
.globl _start\n\
.type _start,@function\n\
_start:\n\
/* Pass pointer to argument block to _dl_start. */\n\
add %sp,64,%o0\n\
call _dl_start\n\
nop\n\
\n\
mov %o0,%l0\n\
\n\
2:\n\
call 1f\n\
nop\n\
1:\n\
sethi %hi(_GLOBAL_OFFSET_TABLE_-(2b-.)),%l2\n\
sethi %hi(_dl_default_scope),%l3\n\
or %l2,%lo(_GLOBAL_OFFSET_TABLE_-(2b-.)),%l2\n\
or %l3,%lo(_dl_default_scope),%l3\n\
add %o7,%l2,%l1\n\
# %l1 has the GOT. %l3 has _dl_default_scope GOT offset\n\
ld [%l1+%l3],%l4\n\
# %l4 has pointer to _dl_default_scope. Now, load _dl_default_scope [2]\n\
ld [%l4+8],%l4\n\
# %l4 has _dl_default_scope [2]\n\
# call _dl_init_next until it returns 0, pass _dl_default_scope [2]\n\
3:\n\
call _dl_init_next\n\
mov %l4,%o0\n\
cmp %o0,%g0\n\
bz,a 4f\n\
nop\n\
call %o0\n\
/* Pass pointer to argument block to this init function */\n\
add %sp,64,%o0\n\
b,a 3b\n\
4:\n\
# Clear the _dl_starting_up variable and pass _dl_fini in %g1 as per ELF ABI.\n\
sethi %hi(_dl_starting_up),%l4\n\
sethi %hi(_dl_fini),%l3\n\
or %l4,%lo(_dl_starting_up),%l4\n\
or %l3,%lo(_dl_fini),%l3\n\
# clear _dl_starting_up\n\
ld [%l1+%l4],%l5\n\
st %g0,[%l5]\n\
# load out fini function for atexit in %g1\n\
ld [%l3+%l1],%g1\n\
# jump to the user program entry point.\n\
jmpl %l0,%g0\n\
nop\n\
");

View File

@ -10,11 +10,13 @@
* This code optimizes short (less than 13-bit) multiplies. * This code optimizes short (less than 13-bit) multiplies.
*/ */
#include "sysdep.h" #include <sysdep.h>
ENTRY(.mul) ENTRY(.mul)
mov %o0, %y ! multiplier -> Y mov %o0, %y ! multiplier -> Y
andncc %o0, 0xfff, %g0 ! test bits 12..31 andncc %o0, 0xfff, %g0 ! test bits 12..31
be Lmul_shortway ! if zero, can do it the short way be LOC(mul_shortway) ! if zero, can do it the short way
andcc %g0, %g0, %o4 ! zero the partial product and clear N and V andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
/* /*
@ -81,7 +83,7 @@ ENTRY(.mul)
! and put upper half in place ! and put upper half in place
#endif #endif
Lmul_shortway: LOC(mul_shortway):
/* /*
* Short multiply. 12 steps, followed by a final shift step. * Short multiply. 12 steps, followed by a final shift step.
* The resulting bits are off by 12 and (32-12) = 20 bit positions, * The resulting bits are off by 12 and (32-12) = 20 bit positions,
@ -121,3 +123,5 @@ Lmul_shortway:
or %o5, %o0, %o0 ! construct low part of result or %o5, %o0, %o0 ! construct low part of result
retl retl
sra %o4, 20, %o1 ! ... and extract high part of result sra %o4, 20, %o1 ! ... and extract high part of result
END(.mul)

View File

@ -0,0 +1,86 @@
/* Startup code for elf32-sparc
Copyright (C) 1997 Free Software Foundation, Inc.
Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <sysdep.h>
.section ".text"
.align 4
.global _start
.type _start,#function
_start:
/* Terminate the stack frame, and reserve space for functions to
drop their arguments. */
mov %g0, %fp
sub %sp, 6*4, %sp
/* Save %g1. When starting a binary via the dynamic linker, %g1
contains the address of the shared library termination function,
which we will register below with atexit() to be called by exit().
If we are statically linked, this will be NULL. */
/* Do essential libc initialization (sp points to argc, argv, and envp) */
call __libc_init_first
mov %g1, %l0
/* Now that we have the proper stack frame, register library termination
function, if there is any: */
cmp %l0, 0
beq 1f
nop
call atexit
mov %l0, %o0
1:
/* Extract the arguments and environment as encoded on the stack. The
argument info starts after one register window (16 words) past the SP. */
ld [%sp+22*4], %o0
add %sp, 23*4, %o1
sll %o0, 4, %o2
add %o2, %o1, %o2
sethi %hi(__environ), %g2
add %o2, 4, %o2
st %o2, [%g2+%lo(__environ)]
mov %o0, %l0 /* tuck them away */
mov %o1, %l1
/* Call _init, the entry point to our own .init section. */
call _init
mov %o2, %l2
/* Register our .fini section with atexit. */
sethi %hi(_fini), %o0
call atexit
add %o0, %lo(_fini), %o0
/* Call the user's main and exit with its return value. */
mov %l0, %o0
mov %l1, %o1
call main
mov %l2, %o2
call exit
nop
/* Die very horribly if exit returns. */
unimp
.size _start,.-_start

View File

@ -1,68 +0,0 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1997 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 Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
extern char **__environ;
extern void __libc_init_first __P ((int argc, char **argv, char **envp));
extern int main __P ((int argc, char **argv, char **envp));
register long int sp asm("%sp"), fp asm("%fp");
void
_start (void)
{
/* It is important that these be declared `register'.
Otherwise, when compiled without optimization, they are put on the
stack, which loses completely after we zero the FP. */
register int argc;
register char **argv, **envp;
register long int g1 asm ("%g1");
unsigned long int copy_g1 = g1;
/* Unwind the frame built when we entered the function. */
asm("restore");
if (copy_g1)
atexit (copy_g1);
/* And clear the frame pointer. */
fp = 0;
/* The argument info starts after one register
window (64 bytes) past the SP. */
argc = ((int *) sp)[16];
argv = (char **) &((int *) sp)[17];
envp = &argv[argc + 1];
__environ = envp;
/* Allocate 24 bytes of stack space for the register save area. */
sp -= 24;
__libc_init_first (argc, argv, envp);
#ifdef ELF_INIT_FINI
{
extern void _fini (void);
_init ();
atexit (_fini);
}
#endif
exit (main (argc, argv, envp));
}

View File

@ -72,5 +72,5 @@ typedef unsigned int fenv_t;
#endif #endif
/* For internal use only: access the fp state register. */ /* For internal use only: access the fp state register. */
#define __fenv_stfsr(X) __asm__("stfsr %0" : "=m"(X)) #define __fenv_stfsr(X) __asm__("st %%fsr,%0" : "=m"(X))
#define __fenv_ldfsr(X) __asm__ __volatile__("ldfsr %0" : : "m"(X)) #define __fenv_ldfsr(X) __asm__ __volatile__("ld %0,%%fsr" : : "m"(X))

View File

@ -41,13 +41,11 @@
/* Now two recommended cw */ /* Now two recommended cw */
/* Linux default: /* Linux and IEEE default:
- extended precision - extended precision
- rounding to nearest - rounding to nearest
- exceptions on overflow, zero divide and NaN */ - no exceptions. */
#define _FPU_DEFAULT 0x1e #define _FPU_DEFAULT 0x0
/* IEEE: same as above, but exceptions */
#define _FPU_IEEE 0x0 #define _FPU_IEEE 0x0
/* Type of the control word. */ /* Type of the control word. */

View File

@ -1,19 +1,19 @@
! sparc __mpn_lshift -- ! Sparc __mpn_lshift --
!
! Copyright (C) 1995, 1996 Free Software Foundation, Inc. ! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library. ! This file is part of the GNU MP Library.
!
! The GNU MP Library is free software; you can redistribute it and/or modify ! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by ! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your ! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version. ! option) any later version.
!
! The GNU MP Library is distributed in the hope that it will be useful, but ! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details. ! License for more details.
!
! You should have received a copy of the GNU Library General Public License ! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to ! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -21,17 +21,14 @@
! INPUT PARAMETERS ! INPUT PARAMETERS
! res_ptr %o0 ! RES_PTR %o0
! src_ptr %o1 ! SRC_PTR %o1
! size %o2 ! SIZE %o2
! cnt %o3 ! CNT %o3
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_lshift)
.align 4
.global C_SYMBOL_NAME(__mpn_lshift)
C_SYMBOL_NAME(__mpn_lshift):
sll %o2,2,%g1 sll %o2,2,%g1
add %o1,%g1,%o1 ! make %o1 point at end of src add %o1,%g1,%o1 ! make %o1 point at end of src
ld [%o1-4],%g2 ! load first limb ld [%o1-4],%g2 ! load first limb
@ -40,12 +37,13 @@ C_SYMBOL_NAME(__mpn_lshift):
add %o2,-1,%o2 add %o2,-1,%o2
andcc %o2,4-1,%g4 ! number of limbs in first loop andcc %o2,4-1,%g4 ! number of limbs in first loop
srl %g2,%o5,%g1 ! compute function result srl %g2,%o5,%g1 ! compute function result
be L0 ! if multiple of 4 limbs, skip first loop be LOC(0) ! if multiple of 4 limbs, skip first loop
st %g1,[%sp+80] st %g1,[%sp+80]
sub %o2,%g4,%o2 ! adjust count for main loop sub %o2,%g4,%o2 ! adjust count for main loop
Loop0: ld [%o1-8],%g3 LOC(loop0):
ld [%o1-8],%g3
add %o0,-4,%o0 add %o0,-4,%o0
add %o1,-4,%o1 add %o1,-4,%o1
addcc %g4,-1,%g4 addcc %g4,-1,%g4
@ -53,14 +51,15 @@ Loop0: ld [%o1-8],%g3
srl %g3,%o5,%g1 srl %g3,%o5,%g1
mov %g3,%g2 mov %g3,%g2
or %o4,%g1,%o4 or %o4,%g1,%o4
bne Loop0 bne LOC(loop0)
st %o4,[%o0+0] st %o4,[%o0+0]
L0: tst %o2 LOC(0): tst %o2
be Lend be LOC(end)
nop nop
Loop: ld [%o1-8],%g3 LOC(loop):
ld [%o1-8],%g3
add %o0,-16,%o0 add %o0,-16,%o0
addcc %o2,-4,%o2 addcc %o2,-4,%o2
sll %g2,%o3,%o4 sll %g2,%o3,%o4
@ -86,10 +85,13 @@ Loop: ld [%o1-8],%g3
add %o1,-16,%o1 add %o1,-16,%o1
or %g4,%g1,%g4 or %g4,%g1,%g4
bne Loop bne LOC(loop)
st %g4,[%o0+0] st %g4,[%o0+0]
Lend: sll %g2,%o3,%g2 LOC(end):
sll %g2,%o3,%g2
st %g2,[%o0-4] st %g2,[%o0-4]
retl retl
ld [%sp+80],%o0 ld [%sp+80],%o0
END(__mpn_lshift)

View File

@ -1,20 +1,20 @@
! SPARC __mpn_mul_1 -- Multiply a limb vector with a limb and store ! SPARC __mpn_mul_1 -- Multiply a limb vector with a limb and store
! the result in a second limb vector. ! the result in a second limb vector.
!
! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. ! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library. ! This file is part of the GNU MP Library.
!
! The GNU MP Library is free software; you can redistribute it and/or modify ! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by ! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your ! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version. ! option) any later version.
!
! The GNU MP Library is distributed in the hope that it will be useful, but ! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details. ! License for more details.
!
! You should have received a copy of the GNU Library General Public License ! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to ! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,10 +22,10 @@
! INPUT PARAMETERS ! INPUT PARAMETERS
! res_ptr o0 ! RES_PTR o0
! s1_ptr o1 ! S1_PTR o1
! size o2 ! SIZE o2
! s2_limb o3 ! S2_LIMB o3
! ADD CODE FOR SMALL MULTIPLIERS! ! ADD CODE FOR SMALL MULTIPLIERS!
!1: ld !1: ld
@ -89,12 +89,9 @@
! sll a,29,y2 ! sll a,29,y2
! st x, ! st x,
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_mul_1)
.align 4
.global C_SYMBOL_NAME(__mpn_mul_1)
C_SYMBOL_NAME(__mpn_mul_1):
! Make S1_PTR and RES_PTR point at the end of their blocks ! Make S1_PTR and RES_PTR point at the end of their blocks
! and put (- 4 x SIZE) in index/loop counter. ! and put (- 4 x SIZE) in index/loop counter.
sll %o2,2,%o2 sll %o2,2,%o2
@ -103,16 +100,16 @@ C_SYMBOL_NAME(__mpn_mul_1):
sub %g0,%o2,%o2 sub %g0,%o2,%o2
cmp %o3,0xfff cmp %o3,0xfff
bgu Large bgu LOC(large)
nop nop
ld [%o1+%o2],%o5 ld [%o1+%o2],%o5
mov 0,%o0 mov 0,%o0
b L0 b LOC(0)
add %o4,-4,%o4 add %o4,-4,%o4
Loop0: LOC(loop0):
st %g1,[%o4+%o2] st %g1,[%o4+%o2]
L0: wr %g0,%o3,%y LOC(0): wr %g0,%o3,%y
sra %o5,31,%g2 sra %o5,31,%g2
and %o3,%g2,%g2 and %o3,%g2,%g2
andcc %g1,0,%g1 andcc %g1,0,%g1
@ -138,21 +135,22 @@ L0: wr %g0,%o3,%y
addcc %g1,%o0,%g1 addcc %g1,%o0,%g1
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter addcc %o2,4,%o2 ! loop counter
bne,a Loop0 bne,a LOC(loop0)
ld [%o1+%o2],%o5 ld [%o1+%o2],%o5
retl retl
st %g1,[%o4+%o2] st %g1,[%o4+%o2]
Large: ld [%o1+%o2],%o5 LOC(large):
ld [%o1+%o2],%o5
mov 0,%o0 mov 0,%o0
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0 sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
b L1 b LOC(1)
add %o4,-4,%o4 add %o4,-4,%o4
Loop: LOC(loop):
st %g3,[%o4+%o2] st %g3,[%o4+%o2]
L1: wr %g0,%o5,%y LOC(1): wr %g0,%o5,%y
and %o5,%g4,%g2 ! g2 = S1_LIMB iff S2_LIMB < 0, else 0 and %o5,%g4,%g2 ! g2 = S1_LIMB iff S2_LIMB < 0, else 0
andcc %g0,%g0,%g1 andcc %g0,%g0,%g1
mulscc %g1,%o3,%g1 mulscc %g1,%o3,%g1
@ -192,8 +190,10 @@ L1: wr %g0,%o5,%y
addcc %g3,%o0,%g3 addcc %g3,%o0,%g3
addx %g2,%g1,%o0 ! add sign-compensation and cy to hi limb addx %g2,%g1,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter addcc %o2,4,%o2 ! loop counter
bne,a Loop bne,a LOC(loop)
ld [%o1+%o2],%o5 ld [%o1+%o2],%o5
retl retl
st %g3,[%o4+%o2] st %g3,[%o4+%o2]
END(__mpn_mul_1)

View File

@ -37,22 +37,14 @@
#include "sysdep.h" #include <sysdep.h>
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sys/trap.h> #include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
ENTRY(.rem) ENTRY(.rem)
! compute sign of result; if neither is negative, no problem ! compute sign of result; if neither is negative, no problem
orcc %o1, %o0, %g0 ! either negative? orcc %o1, %o0, %g0 ! either negative?
bge 2f ! no, go do the divide bge 2f ! no, go do the divide
mov %o0, %g6 ! sign of remainder matches %o0 mov %o0, %g3 ! sign of remainder matches %o0
tst %o1 tst %o1
bge 1f bge 1f
tst %o0 tst %o0
@ -76,11 +68,11 @@ ENTRY(.rem)
1: 1:
cmp %o3, %o5 ! if %o1 exceeds %o0, done cmp %o3, %o5 ! if %o1 exceeds %o0, done
blu Lgot_result ! (and algorithm fails otherwise) blu LOC(got_result) ! (and algorithm fails otherwise)
clr %o2 clr %o2
sethi %hi(1 << (32 - 4 - 1)), %g1 sethi %hi(1 << (32 - 4 - 1)), %g1
cmp %o3, %g1 cmp %o3, %g1
blu Lnot_really_big blu LOC(not_really_big)
clr %o4 clr %o4
! Here the dividend is >= 2**(31-N) or so. We must be careful here, ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
@ -91,15 +83,15 @@ ENTRY(.rem)
1: 1:
cmp %o5, %g1 cmp %o5, %g1
bgeu 3f bgeu 3f
mov 1, %g7 mov 1, %g2
sll %o5, 4, %o5 sll %o5, 4, %o5
b 1b b 1b
add %o4, 1, %o4 add %o4, 1, %o4
! Now compute %g7. ! Now compute %g2.
2: addcc %o5, %o5, %o5 2: addcc %o5, %o5, %o5
bcc Lnot_too_big bcc LOC(not_too_big)
add %g7, 1, %g7 add %g2, 1, %g2
! We get here if the %o1 overflowed while shifting. ! We get here if the %o1 overflowed while shifting.
! This means that %o3 has the high-order bit set. ! This means that %o3 has the high-order bit set.
@ -107,20 +99,20 @@ ENTRY(.rem)
sll %g1, 4, %g1 ! high order bit sll %g1, 4, %g1 ! high order bit
srl %o5, 1, %o5 ! rest of %o5 srl %o5, 1, %o5 ! rest of %o5
add %o5, %g1, %o5 add %o5, %g1, %o5
b Ldo_single_div b LOC(do_single_div)
sub %g7, 1, %g7 sub %g2, 1, %g2
Lnot_too_big: LOC(not_too_big):
3: cmp %o5, %o3 3: cmp %o5, %o3
blu 2b blu 2b
nop nop
be Ldo_single_div be LOC(do_single_div)
nop nop
/* NB: these are commented out in the V8-Sparc manual as well */ /* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */ /* (I do not understand this) */
! %o5 > %o3: went too far: back up 1 step ! %o5 > %o3: went too far: back up 1 step
! srl %o5, 1, %o5 ! srl %o5, 1, %o5
! dec %g7 ! dec %g2
! do single-bit divide steps ! do single-bit divide steps
! !
! We have to be careful here. We know that %o3 >= %o5, so we can do the ! We have to be careful here. We know that %o3 >= %o5, so we can do the
@ -129,15 +121,15 @@ ENTRY(.rem)
! order bit set in the first step, just falling into the regular ! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around. ! division loop will mess up the first time around.
! So we unroll slightly... ! So we unroll slightly...
Ldo_single_div: LOC(do_single_div):
subcc %g7, 1, %g7 subcc %g2, 1, %g2
bl Lend_regular_divide bl LOC(end_regular_divide)
nop nop
sub %o3, %o5, %o3 sub %o3, %o5, %o3
mov 1, %o2 mov 1, %o2
b Lend_single_divloop b LOC(end_single_divloop)
nop nop
Lsingle_divloop: LOC(single_divloop):
sll %o2, 1, %o2 sll %o2, 1, %o2
bl 1f bl 1f
srl %o5, 1, %o5 srl %o5, 1, %o5
@ -149,221 +141,223 @@ ENTRY(.rem)
add %o3, %o5, %o3 add %o3, %o5, %o3
sub %o2, 1, %o2 sub %o2, 1, %o2
2: 2:
Lend_single_divloop: LOC(end_single_divloop):
subcc %g7, 1, %g7 subcc %g2, 1, %g2
bge Lsingle_divloop bge LOC(single_divloop)
tst %o3 tst %o3
b,a Lend_regular_divide b,a LOC(end_regular_divide)
Lnot_really_big: LOC(not_really_big):
1: 1:
sll %o5, 4, %o5 sll %o5, 4, %o5
cmp %o5, %o3 cmp %o5, %o3
bleu 1b bleu 1b
addcc %o4, 1, %o4 addcc %o4, 1, %o4
be Lgot_result be LOC(got_result)
sub %o4, 1, %o4 sub %o4, 1, %o4
tst %o3 ! set up for initial iteration tst %o3 ! set up for initial iteration
Ldivloop: LOC(divloop):
sll %o2, 4, %o2 sll %o2, 4, %o2
! depth 1, accumulated bits 0 ! depth 1, accumulated bits 0
bl L.1.16 bl LOC(1.16)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 2, accumulated bits 1 ! depth 2, accumulated bits 1
bl L.2.17 bl LOC(2.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 3, accumulated bits 3 ! depth 3, accumulated bits 3
bl L.3.19 bl LOC(3.19)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits 7 ! depth 4, accumulated bits 7
bl L.4.23 bl LOC(4.23)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (7*2+1), %o2 add %o2, (7*2+1), %o2
L.4.23: LOC(4.23):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (7*2-1), %o2 add %o2, (7*2-1), %o2
L.3.19: LOC(3.19):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits 5 ! depth 4, accumulated bits 5
bl L.4.21 bl LOC(4.21)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (5*2+1), %o2 add %o2, (5*2+1), %o2
L.4.21: LOC(4.21):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (5*2-1), %o2 add %o2, (5*2-1), %o2
L.2.17: LOC(2.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 3, accumulated bits 1 ! depth 3, accumulated bits 1
bl L.3.17 bl LOC(3.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits 3 ! depth 4, accumulated bits 3
bl L.4.19 bl LOC(4.19)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (3*2+1), %o2 add %o2, (3*2+1), %o2
L.4.19: LOC(4.19):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (3*2-1), %o2 add %o2, (3*2-1), %o2
L.3.17: LOC(3.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits 1 ! depth 4, accumulated bits 1
bl L.4.17 bl LOC(4.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (1*2+1), %o2 add %o2, (1*2+1), %o2
L.4.17: LOC(4.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (1*2-1), %o2 add %o2, (1*2-1), %o2
L.1.16: LOC(1.16):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 2, accumulated bits -1 ! depth 2, accumulated bits -1
bl L.2.15 bl LOC(2.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 3, accumulated bits -1 ! depth 3, accumulated bits -1
bl L.3.15 bl LOC(3.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits -1 ! depth 4, accumulated bits -1
bl L.4.15 bl LOC(4.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-1*2+1), %o2 add %o2, (-1*2+1), %o2
L.4.15: LOC(4.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-1*2-1), %o2 add %o2, (-1*2-1), %o2
L.3.15: LOC(3.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits -3 ! depth 4, accumulated bits -3
bl L.4.13 bl LOC(4.13)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-3*2+1), %o2 add %o2, (-3*2+1), %o2
L.4.13: LOC(4.13):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-3*2-1), %o2 add %o2, (-3*2-1), %o2
L.2.15: LOC(2.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 3, accumulated bits -3 ! depth 3, accumulated bits -3
bl L.3.13 bl LOC(3.13)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits -5 ! depth 4, accumulated bits -5
bl L.4.11 bl LOC(4.11)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-5*2+1), %o2 add %o2, (-5*2+1), %o2
L.4.11: LOC(4.11):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-5*2-1), %o2 add %o2, (-5*2-1), %o2
L.3.13: LOC(3.13):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits -7 ! depth 4, accumulated bits -7
bl L.4.9 bl LOC(4.9)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-7*2+1), %o2 add %o2, (-7*2+1), %o2
L.4.9: LOC(4.9):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-7*2-1), %o2 add %o2, (-7*2-1), %o2
9: 9:
Lend_regular_divide: LOC(end_regular_divide):
subcc %o4, 1, %o4 subcc %o4, 1, %o4
bge Ldivloop bge LOC(divloop)
tst %o3 tst %o3
bl,a Lgot_result bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!) ! non-restoring fixup here (one instruction only!)
add %o3, %o1, %o3 add %o3, %o1, %o3
Lgot_result: LOC(got_result):
! check to see if answer should be < 0 ! check to see if answer should be < 0
tst %g6 tst %g3
bl,a 1f bl,a 1f
sub %g0, %o3, %o3 sub %g0, %o3, %o3
1: 1:
retl retl
mov %o3, %o0 mov %o3, %o0
END(.rem)

View File

@ -1,19 +1,19 @@
! sparc __mpn_rshift -- ! sparc __mpn_rshift --
!
! Copyright (C) 1995, 1996 Free Software Foundation, Inc. ! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library. ! This file is part of the GNU MP Library.
!
! The GNU MP Library is free software; you can redistribute it and/or modify ! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by ! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your ! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version. ! option) any later version.
!
! The GNU MP Library is distributed in the hope that it will be useful, but ! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details. ! License for more details.
!
! You should have received a copy of the GNU Library General Public License ! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to ! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -21,28 +21,26 @@
! INPUT PARAMETERS ! INPUT PARAMETERS
! res_ptr %o0 ! RES_PTR %o0
! src_ptr %o1 ! SRC_PTR %o1
! size %o2 ! SIZE %o2
! cnt %o3 ! CNT %o3
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_rshift)
.align 4
.global C_SYMBOL_NAME(__mpn_rshift)
C_SYMBOL_NAME(__mpn_rshift):
ld [%o1],%g2 ! load first limb ld [%o1],%g2 ! load first limb
sub %g0,%o3,%o5 ! negate shift count sub %g0,%o3,%o5 ! negate shift count
add %o2,-1,%o2 add %o2,-1,%o2
andcc %o2,4-1,%g4 ! number of limbs in first loop andcc %o2,4-1,%g4 ! number of limbs in first loop
sll %g2,%o5,%g1 ! compute function result sll %g2,%o5,%g1 ! compute function result
be L0 ! if multiple of 4 limbs, skip first loop be LOC(0) ! if multiple of 4 limbs, skip first loop
st %g1,[%sp+80] st %g1,[%sp+80]
sub %o2,%g4,%o2 ! adjust count for main loop sub %o2,%g4,%o2 ! adjust count for main loop
Loop0: ld [%o1+4],%g3 LOC(loop0):
ld [%o1+4],%g3
add %o0,4,%o0 add %o0,4,%o0
add %o1,4,%o1 add %o1,4,%o1
addcc %g4,-1,%g4 addcc %g4,-1,%g4
@ -50,14 +48,15 @@ Loop0: ld [%o1+4],%g3
sll %g3,%o5,%g1 sll %g3,%o5,%g1
mov %g3,%g2 mov %g3,%g2
or %o4,%g1,%o4 or %o4,%g1,%o4
bne Loop0 bne LOC(loop0)
st %o4,[%o0-4] st %o4,[%o0-4]
L0: tst %o2 LOC(0): tst %o2
be Lend be LOC(end)
nop nop
Loop: ld [%o1+4],%g3 LOC(loop):
ld [%o1+4],%g3
add %o0,16,%o0 add %o0,16,%o0
addcc %o2,-4,%o2 addcc %o2,-4,%o2
srl %g2,%o3,%o4 srl %g2,%o3,%o4
@ -83,10 +82,13 @@ Loop: ld [%o1+4],%g3
add %o1,16,%o1 add %o1,16,%o1
or %g4,%g1,%g4 or %g4,%g1,%g4
bne Loop bne LOC(loop)
st %g4,[%o0-4] st %g4,[%o0-4]
Lend: srl %g2,%o3,%g2 LOC(end):
srl %g2,%o3,%g2
st %g2,[%o0-0] st %g2,[%o0-0]
retl retl
ld [%sp+80],%o0 ld [%sp+80],%o0
END(__mpn_rshift)

View File

@ -37,22 +37,14 @@
#include "sysdep.h" #include <sysdep.h>
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sys/trap.h> #include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
ENTRY(.div) ENTRY(.div)
! compute sign of result; if neither is negative, no problem ! compute sign of result; if neither is negative, no problem
orcc %o1, %o0, %g0 ! either negative? orcc %o1, %o0, %g0 ! either negative?
bge 2f ! no, go do the divide bge 2f ! no, go do the divide
xor %o1, %o0, %g6 ! compute sign in any case xor %o1, %o0, %g3 ! compute sign in any case
tst %o1 tst %o1
bge 1f bge 1f
tst %o0 tst %o0
@ -76,11 +68,11 @@ ENTRY(.div)
1: 1:
cmp %o3, %o5 ! if %o1 exceeds %o0, done cmp %o3, %o5 ! if %o1 exceeds %o0, done
blu Lgot_result ! (and algorithm fails otherwise) blu LOC(got_result) ! (and algorithm fails otherwise)
clr %o2 clr %o2
sethi %hi(1 << (32 - 4 - 1)), %g1 sethi %hi(1 << (32 - 4 - 1)), %g1
cmp %o3, %g1 cmp %o3, %g1
blu Lnot_really_big blu LOC(not_really_big)
clr %o4 clr %o4
! Here the dividend is >= 2**(31-N) or so. We must be careful here, ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
@ -91,15 +83,15 @@ ENTRY(.div)
1: 1:
cmp %o5, %g1 cmp %o5, %g1
bgeu 3f bgeu 3f
mov 1, %g7 mov 1, %g2
sll %o5, 4, %o5 sll %o5, 4, %o5
b 1b b 1b
add %o4, 1, %o4 add %o4, 1, %o4
! Now compute %g7. ! Now compute %g2.
2: addcc %o5, %o5, %o5 2: addcc %o5, %o5, %o5
bcc Lnot_too_big bcc LOC(not_too_big)
add %g7, 1, %g7 add %g2, 1, %g2
! We get here if the %o1 overflowed while shifting. ! We get here if the %o1 overflowed while shifting.
! This means that %o3 has the high-order bit set. ! This means that %o3 has the high-order bit set.
@ -107,20 +99,20 @@ ENTRY(.div)
sll %g1, 4, %g1 ! high order bit sll %g1, 4, %g1 ! high order bit
srl %o5, 1, %o5 ! rest of %o5 srl %o5, 1, %o5 ! rest of %o5
add %o5, %g1, %o5 add %o5, %g1, %o5
b Ldo_single_div b LOC(do_single_div)
sub %g7, 1, %g7 sub %g2, 1, %g2
Lnot_too_big: LOC(not_too_big):
3: cmp %o5, %o3 3: cmp %o5, %o3
blu 2b blu 2b
nop nop
be Ldo_single_div be LOC(do_single_div)
nop nop
/* NB: these are commented out in the V8-Sparc manual as well */ /* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */ /* (I do not understand this) */
! %o5 > %o3: went too far: back up 1 step ! %o5 > %o3: went too far: back up 1 step
! srl %o5, 1, %o5 ! srl %o5, 1, %o5
! dec %g7 ! dec %g2
! do single-bit divide steps ! do single-bit divide steps
! !
! We have to be careful here. We know that %o3 >= %o5, so we can do the ! We have to be careful here. We know that %o3 >= %o5, so we can do the
@ -129,15 +121,15 @@ ENTRY(.div)
! order bit set in the first step, just falling into the regular ! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around. ! division loop will mess up the first time around.
! So we unroll slightly... ! So we unroll slightly...
Ldo_single_div: LOC(do_single_div):
subcc %g7, 1, %g7 subcc %g2, 1, %g2
bl Lend_regular_divide bl LOC(end_regular_divide)
nop nop
sub %o3, %o5, %o3 sub %o3, %o5, %o3
mov 1, %o2 mov 1, %o2
b Lend_single_divloop b LOC(end_single_divloop)
nop nop
Lsingle_divloop: LOC(single_divloop):
sll %o2, 1, %o2 sll %o2, 1, %o2
bl 1f bl 1f
srl %o5, 1, %o5 srl %o5, 1, %o5
@ -149,221 +141,223 @@ ENTRY(.div)
add %o3, %o5, %o3 add %o3, %o5, %o3
sub %o2, 1, %o2 sub %o2, 1, %o2
2: 2:
Lend_single_divloop: LOC(end_single_divloop):
subcc %g7, 1, %g7 subcc %g2, 1, %g2
bge Lsingle_divloop bge LOC(single_divloop)
tst %o3 tst %o3
b,a Lend_regular_divide b,a LOC(end_regular_divide)
Lnot_really_big: LOC(not_really_big):
1: 1:
sll %o5, 4, %o5 sll %o5, 4, %o5
cmp %o5, %o3 cmp %o5, %o3
bleu 1b bleu 1b
addcc %o4, 1, %o4 addcc %o4, 1, %o4
be Lgot_result be LOC(got_result)
sub %o4, 1, %o4 sub %o4, 1, %o4
tst %o3 ! set up for initial iteration tst %o3 ! set up for initial iteration
Ldivloop: LOC(divloop):
sll %o2, 4, %o2 sll %o2, 4, %o2
! depth 1, accumulated bits 0 ! depth 1, accumulated bits 0
bl L.1.16 bl LOC(1.16)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 2, accumulated bits 1 ! depth 2, accumulated bits 1
bl L.2.17 bl LOC(2.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 3, accumulated bits 3 ! depth 3, accumulated bits 3
bl L.3.19 bl LOC(3.19)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits 7 ! depth 4, accumulated bits 7
bl L.4.23 bl LOC(4.23)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (7*2+1), %o2 add %o2, (7*2+1), %o2
L.4.23: LOC(4.23):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (7*2-1), %o2 add %o2, (7*2-1), %o2
L.3.19: LOC(3.19):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits 5 ! depth 4, accumulated bits 5
bl L.4.21 bl LOC(4.21)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (5*2+1), %o2 add %o2, (5*2+1), %o2
L.4.21: LOC(4.21):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (5*2-1), %o2 add %o2, (5*2-1), %o2
L.2.17: LOC(2.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 3, accumulated bits 1 ! depth 3, accumulated bits 1
bl L.3.17 bl LOC(3.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits 3 ! depth 4, accumulated bits 3
bl L.4.19 bl LOC(4.19)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (3*2+1), %o2 add %o2, (3*2+1), %o2
L.4.19: LOC(4.19):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (3*2-1), %o2 add %o2, (3*2-1), %o2
L.3.17: LOC(3.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits 1 ! depth 4, accumulated bits 1
bl L.4.17 bl LOC(4.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (1*2+1), %o2 add %o2, (1*2+1), %o2
L.4.17: LOC(4.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (1*2-1), %o2 add %o2, (1*2-1), %o2
L.1.16: LOC(1.16):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 2, accumulated bits -1 ! depth 2, accumulated bits -1
bl L.2.15 bl LOC(2.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 3, accumulated bits -1 ! depth 3, accumulated bits -1
bl L.3.15 bl LOC(3.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits -1 ! depth 4, accumulated bits -1
bl L.4.15 bl LOC(4.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-1*2+1), %o2 add %o2, (-1*2+1), %o2
L.4.15: LOC(4.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-1*2-1), %o2 add %o2, (-1*2-1), %o2
L.3.15: LOC(3.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits -3 ! depth 4, accumulated bits -3
bl L.4.13 bl LOC(4.13)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-3*2+1), %o2 add %o2, (-3*2+1), %o2
L.4.13: LOC(4.13):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-3*2-1), %o2 add %o2, (-3*2-1), %o2
L.2.15: LOC(2.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 3, accumulated bits -3 ! depth 3, accumulated bits -3
bl L.3.13 bl LOC(3.13)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits -5 ! depth 4, accumulated bits -5
bl L.4.11 bl LOC(4.11)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-5*2+1), %o2 add %o2, (-5*2+1), %o2
L.4.11: LOC(4.11):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-5*2-1), %o2 add %o2, (-5*2-1), %o2
L.3.13: LOC(3.13):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits -7 ! depth 4, accumulated bits -7
bl L.4.9 bl LOC(4.9)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-7*2+1), %o2 add %o2, (-7*2+1), %o2
L.4.9: LOC(4.9):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-7*2-1), %o2 add %o2, (-7*2-1), %o2
9: 9:
Lend_regular_divide: LOC(end_regular_divide):
subcc %o4, 1, %o4 subcc %o4, 1, %o4
bge Ldivloop bge LOC(divloop)
tst %o3 tst %o3
bl,a Lgot_result bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!) ! non-restoring fixup here (one instruction only!)
sub %o2, 1, %o2 sub %o2, 1, %o2
Lgot_result: LOC(got_result):
! check to see if answer should be < 0 ! check to see if answer should be < 0
tst %g6 tst %g3
bl,a 1f bl,a 1f
sub %g0, %o2, %o2 sub %g0, %o2, %o2
1: 1:
retl retl
mov %o2, %o0 mov %o2, %o0
END(.div)

View File

@ -22,33 +22,29 @@
#define _ASM 1 #define _ASM 1
#include <bits/setjmp.h> #include <bits/setjmp.h>
ENTRY(_setjmp)
b 1f
set 0, %o1
END(_setjmp)
ENTRY(setjmp)
set 1, %o1
END(setjmp)
ENTRY (__sigsetjmp) ENTRY (__sigsetjmp)
/* Save our SP and FP; in the delay slot of the jump, save our
return PC. Save the signal mask if requested with a tail-call
for simplicity; it always returns zero. */
ta ST_FLUSH_WINDOWS
#ifdef PIC
mov %o7,%g1
2:
call 1f
nop
1: 1:
sethi %hi(_GLOBAL_OFFSET_TABLE_-(2b-.)),%g2 /* Save our PC, SP and FP. Save the signal mask if requested with
or %g2,%lo(_GLOBAL_OFFSET_TABLE_-(2b-.)),%g2 a tail-call for simplicity; it always returns zero. */
add %g2,%o7,%g2 ta ST_FLUSH_WINDOWS
sethi %hi(C_SYMBOL_NAME (__sigjmp_save)), %g3
or %g3,%lo(C_SYMBOL_NAME (__sigjmp_save)), %g3 st %o7, [%o0 + (JB_PC * 4)]
st %sp, [%o0 + (JB_SP * 4)] st %sp, [%o0 + (JB_SP * 4)]
st %fp, [%o0 + (JB_FP * 4)] st %fp, [%o0 + (JB_FP * 4)]
mov %g1,%o7
ld [%g2+%g3],%g1 mov %o7, %g1
jmp %g1 call __sigjmp_save
st %o7, [%o0+(JB_PC*4)] mov %g1, %o7
#else END(__sigsetjmp)
sethi %hi(C_SYMBOL_NAME (__sigjmp_save)), %g1
st %sp, [%o0 + (JB_SP*4)] weak_extern(_setjmp)
or %lo(C_SYMBOL_NAME (__sigjmp_save)), %g1, %g1 weak_extern(setjmp)
st %fp, [%o0 + (JB_FP*4)]
jmp %g1
st %o7, [%o0 + (JB_PC*4)]
#endif /* PIC */

View File

@ -27,54 +27,52 @@
! size o2 ! size o2
! s2_limb o3 ! s2_limb o3
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_addmul_1)
.align 4
.global C_SYMBOL_NAME(__mpn_addmul_1)
C_SYMBOL_NAME(__mpn_addmul_1):
orcc %g0,%g0,%g2
ld [%o1+0],%o4 ! 1 ld [%o1+0],%o4 ! 1
sll %o2,4,%g1 sll %o2,4,%g1
and %g1,(4-1)<<4,%g1 orcc %g0,%g0,%g2
#if PIC
mov %o7,%g4 ! Save return address register mov %o7,%g4 ! Save return address register
call 1f and %g1,(4-1)<<4,%g1
add %o7,LL-1f,%g3 1: call 2f
1: mov %g4,%o7 ! Restore return address register add %o7,3f-1b,%g3
#else 2: jmp %g3+%g1
sethi %hi(LL),%g3 mov %g4,%o7 ! Restore return address register
or %g3,%lo(LL),%g3
#endif .align 4
jmp %g3+%g1 3:
LOC(00):
add %o0,-4,%o0
b LOC(loop00) /* 4, 8, 12, ... */
add %o1,-4,%o1
nop nop
LL: LOC(01):
LL00: add %o0,-4,%o0 b LOC(loop01) /* 1, 5, 9, ... */
b Loop00 /* 4, 8, 12, ... */ nop
add %o1,-4,%o1
nop
LL01: b Loop01 /* 1, 5, 9, ... */
nop nop
nop nop
LOC(10):
add %o0,-12,%o0 /* 2, 6, 10, ... */
b LOC(loop10)
add %o1,4,%o1
nop nop
LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */ LOC(11):
b Loop10 add %o0,-8,%o0 /* 3, 7, 11, ... */
add %o1,4,%o1 b LOC(loop11)
nop add %o1,-8,%o1
LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
b Loop11
add %o1,-8,%o1
nop nop
1: addcc %g3,%g2,%g3 ! 1 LOC(loop):
addcc %g3,%g2,%g3 ! 1
ld [%o1+4],%o4 ! 2 ld [%o1+4],%o4 ! 2
rd %y,%g2 ! 1 rd %y,%g2 ! 1
addx %g0,%g2,%g2 addx %g0,%g2,%g2
ld [%o0+0],%g1 ! 2 ld [%o0+0],%g1 ! 2
addcc %g1,%g3,%g3 addcc %g1,%g3,%g3
st %g3,[%o0+0] ! 1 st %g3,[%o0+0] ! 1
Loop00: umul %o4,%o3,%g3 ! 2 LOC(loop00):
umul %o4,%o3,%g3 ! 2
ld [%o0+4],%g1 ! 2 ld [%o0+4],%g1 ! 2
addxcc %g3,%g2,%g3 ! 2 addxcc %g3,%g2,%g3 ! 2
ld [%o1+8],%o4 ! 3 ld [%o1+8],%o4 ! 3
@ -83,7 +81,8 @@ Loop00: umul %o4,%o3,%g3 ! 2
nop nop
addcc %g1,%g3,%g3 addcc %g1,%g3,%g3
st %g3,[%o0+4] ! 2 st %g3,[%o0+4] ! 2
Loop11: umul %o4,%o3,%g3 ! 3 LOC(loop11):
umul %o4,%o3,%g3 ! 3
addxcc %g3,%g2,%g3 ! 3 addxcc %g3,%g2,%g3 ! 3
ld [%o1+12],%o4 ! 4 ld [%o1+12],%o4 ! 4
rd %y,%g2 ! 3 rd %y,%g2 ! 3
@ -92,7 +91,8 @@ Loop11: umul %o4,%o3,%g3 ! 3
ld [%o0+8],%g1 ! 2 ld [%o0+8],%g1 ! 2
addcc %g1,%g3,%g3 addcc %g1,%g3,%g3
st %g3,[%o0+8] ! 3 st %g3,[%o0+8] ! 3
Loop10: umul %o4,%o3,%g3 ! 4 LOC(loop10):
umul %o4,%o3,%g3 ! 4
addxcc %g3,%g2,%g3 ! 4 addxcc %g3,%g2,%g3 ! 4
ld [%o1+0],%o4 ! 1 ld [%o1+0],%o4 ! 1
rd %y,%g2 ! 4 rd %y,%g2 ! 4
@ -102,9 +102,10 @@ Loop10: umul %o4,%o3,%g3 ! 4
st %g3,[%o0+12] ! 4 st %g3,[%o0+12] ! 4
add %o0,16,%o0 add %o0,16,%o0
addx %g0,%g2,%g2 addx %g0,%g2,%g2
Loop01: addcc %o2,-4,%o2 LOC(loop01):
bg 1b addcc %o2,-4,%o2
umul %o4,%o3,%g3 ! 1 bg LOC(loop)
umul %o4,%o3,%g3 ! 1
addcc %g3,%g2,%g3 ! 4 addcc %g3,%g2,%g3 ! 4
rd %y,%g2 ! 4 rd %y,%g2 ! 4
@ -112,13 +113,7 @@ Loop01: addcc %o2,-4,%o2
ld [%o0+0],%g1 ! 2 ld [%o0+0],%g1 ! 2
addcc %g1,%g3,%g3 addcc %g1,%g3,%g3
st %g3,[%o0+0] ! 4 st %g3,[%o0+0] ! 4
addx %g0,%g2,%o0
retl retl
nop addx %g0,%g2,%o0
! umul, ld, addxcc, rd, st
! umul, ld, addxcc, rd, ld, addcc, st, addx
END(__mpn_addmul_1)

View File

@ -0,0 +1,13 @@
/*
* Sparc v8 has multiply.
*/
#include <sysdep.h>
ENTRY(.mul)
smul %o0, %o1, %o0
retl
rd %y, %o1
END(.mul)

View File

@ -27,73 +27,77 @@
! size o2 ! size o2
! s2_limb o3 ! s2_limb o3
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_mul_1)
.align 8
.global C_SYMBOL_NAME(__mpn_mul_1)
C_SYMBOL_NAME(__mpn_mul_1):
sll %o2,4,%g1 sll %o2,4,%g1
and %g1,(4-1)<<4,%g1
#if PIC
mov %o7,%g4 ! Save return address register mov %o7,%g4 ! Save return address register
call 1f and %g1,(4-1)<<4,%g1
add %o7,LL-1f,%g3 1: call 2f
1: mov %g4,%o7 ! Restore return address register add %o7,3f-1b,%g3
#else 2: mov %g4,%o7 ! Restore return address register
sethi %hi(LL),%g3
or %g3,%lo(LL),%g3
#endif
jmp %g3+%g1 jmp %g3+%g1
ld [%o1+0],%o4 ! 1 ld [%o1+0],%o4 ! 1
LL:
LL00: add %o0,-4,%o0
add %o1,-4,%o1
b Loop00 /* 4, 8, 12, ... */
orcc %g0,%g0,%g2
LL01: b Loop01 /* 1, 5, 9, ... */
orcc %g0,%g0,%g2
nop
nop
LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
add %o1,4,%o1
b Loop10
orcc %g0,%g0,%g2
nop
LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
add %o1,-8,%o1
b Loop11
orcc %g0,%g0,%g2
Loop: addcc %g3,%g2,%g3 ! 1 .align 4
3:
LOC(00):
add %o0,-4,%o0
add %o1,-4,%o1
b LOC(loop00) /* 4, 8, 12, ... */
orcc %g0,%g0,%g2
LOC(01):
b LOC(loop01) /* 1, 5, 9, ... */
orcc %g0,%g0,%g2
nop
nop
LOC(10):
add %o0,-12,%o0 /* 2, 6, 10, ... */
add %o1,4,%o1
b LOC(loop10)
orcc %g0,%g0,%g2
nop
LOC(11):
add %o0,-8,%o0 /* 3, 7, 11, ... */
add %o1,-8,%o1
b LOC(loop11)
orcc %g0,%g0,%g2
LOC(loop):
addcc %g3,%g2,%g3 ! 1
ld [%o1+4],%o4 ! 2 ld [%o1+4],%o4 ! 2
st %g3,[%o0+0] ! 1 st %g3,[%o0+0] ! 1
rd %y,%g2 ! 1 rd %y,%g2 ! 1
Loop00: umul %o4,%o3,%g3 ! 2 LOC(loop00):
umul %o4,%o3,%g3 ! 2
addxcc %g3,%g2,%g3 ! 2 addxcc %g3,%g2,%g3 ! 2
ld [%o1+8],%o4 ! 3 ld [%o1+8],%o4 ! 3
st %g3,[%o0+4] ! 2 st %g3,[%o0+4] ! 2
rd %y,%g2 ! 2 rd %y,%g2 ! 2
Loop11: umul %o4,%o3,%g3 ! 3 LOC(loop11):
umul %o4,%o3,%g3 ! 3
addxcc %g3,%g2,%g3 ! 3 addxcc %g3,%g2,%g3 ! 3
ld [%o1+12],%o4 ! 4 ld [%o1+12],%o4 ! 4
add %o1,16,%o1 add %o1,16,%o1
st %g3,[%o0+8] ! 3 st %g3,[%o0+8] ! 3
rd %y,%g2 ! 3 rd %y,%g2 ! 3
Loop10: umul %o4,%o3,%g3 ! 4 LOC(loop10):
umul %o4,%o3,%g3 ! 4
addxcc %g3,%g2,%g3 ! 4 addxcc %g3,%g2,%g3 ! 4
ld [%o1+0],%o4 ! 1 ld [%o1+0],%o4 ! 1
st %g3,[%o0+12] ! 4 st %g3,[%o0+12] ! 4
add %o0,16,%o0 add %o0,16,%o0
rd %y,%g2 ! 4 rd %y,%g2 ! 4
addx %g0,%g2,%g2 addx %g0,%g2,%g2
Loop01: addcc %o2,-4,%o2 LOC(loop01):
bg Loop addcc %o2,-4,%o2
umul %o4,%o3,%g3 ! 1 bg LOC(loop)
umul %o4,%o3,%g3 ! 1
addcc %g3,%g2,%g3 ! 4 addcc %g3,%g2,%g3 ! 4
st %g3,[%o0+0] ! 4 st %g3,[%o0+0] ! 4
rd %y,%g2 ! 4 rd %y,%g2 ! 4
retl retl
addx %g0,%g2,%o0 addx %g0,%g2,%o0
END(__mpn_mul_1)

View File

@ -0,0 +1,18 @@
/*
* Sparc v8 has divide.
*/
#include <sysdep.h>
ENTRY(.rem)
sra %o0, 31, %o2
wr %o2, 0, %y
sdivcc %o0, %o1, %o2
bvs,a 1f
xnor %o2, %g0, %o2
1: smul %o2, %o1, %o2
retl
sub %o0, %o2, %o0
END(.rem)

View File

@ -0,0 +1,14 @@
/*
* Sparc v8 has divide.
*/
#include <sysdep.h>
ENTRY(.div)
sra %o0, 31, %o2
wr %o2, 0, %y
ret
sdiv %o0, %o1, %o0
END(.div)

View File

@ -27,12 +27,9 @@
! size o2 ! size o2
! s2_limb o3 ! s2_limb o3
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_submul_1)
.align 4
.global C_SYMBOL_NAME(__mpn_submul_1)
C_SYMBOL_NAME(__mpn_submul_1):
sub %g0,%o2,%o2 ! negate ... sub %g0,%o2,%o2 ! negate ...
sll %o2,2,%o2 ! ... and scale size sll %o2,2,%o2 ! ... and scale size
sub %o1,%o2,%o1 ! o1 is offset s1_ptr sub %o1,%o2,%o1 ! o1 is offset s1_ptr
@ -40,7 +37,8 @@ C_SYMBOL_NAME(__mpn_submul_1):
mov 0,%o0 ! clear cy_limb mov 0,%o0 ! clear cy_limb
Loop: ld [%o1+%o2],%o4 LOC(loop):
ld [%o1+%o2],%o4
ld [%g1+%o2],%g2 ld [%g1+%o2],%g2
umul %o4,%o3,%o5 umul %o4,%o3,%o5
rd %y,%g3 rd %y,%g3
@ -51,8 +49,10 @@ Loop: ld [%o1+%o2],%o4
st %g2,[%g1+%o2] st %g2,[%g1+%o2]
addcc %o2,4,%o2 addcc %o2,4,%o2
bne Loop bne LOC(loop)
nop nop
retl retl
nop nop
END(__mpn_submul_1)

View File

@ -0,0 +1,13 @@
/*
* Sparc v8 has divide.
*/
#include <sysdep.h>
ENTRY(.udiv)
wr %g0, 0, %y
retl
udiv %o0, %o1, %o0
END(.udiv)

View File

@ -27,66 +27,75 @@
#include "sysdep.h" #include "sysdep.h"
.text ENTRY(__udiv_qrnnd)
.align 4
.global C_SYMBOL_NAME(__udiv_qrnnd)
C_SYMBOL_NAME(__udiv_qrnnd):
tst %o3 tst %o3
bneg Largedivisor bneg LOC(largedivisor)
mov 8,%g1 mov 8,%g1
b Lp1 b LOC(p1)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Lplop: bcc Ln1 LOC(plop):
bcc LOC(n1)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Lp1: addx %o1,%o1,%o1 LOC(p1):
addx %o1,%o1,%o1
subcc %o1,%o3,%o4 subcc %o1,%o3,%o4
bcc Ln2 bcc LOC(n2)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Lp2: addx %o1,%o1,%o1 LOC(p2):
addx %o1,%o1,%o1
subcc %o1,%o3,%o4 subcc %o1,%o3,%o4
bcc Ln3 bcc LOC(n3)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Lp3: addx %o1,%o1,%o1 LOC(p3):
addx %o1,%o1,%o1
subcc %o1,%o3,%o4 subcc %o1,%o3,%o4
bcc Ln4 bcc LOC(n4)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Lp4: addx %o1,%o1,%o1 LOC(p4):
addx %o1,%o1,%o1
addcc %g1,-1,%g1 addcc %g1,-1,%g1
bne Lplop bne LOC(plop)
subcc %o1,%o3,%o4 subcc %o1,%o3,%o4
bcc Ln5 bcc LOC(n5)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Lp5: st %o1,[%o0] LOC(p5):
st %o1,[%o0]
retl retl
xnor %g0,%o2,%o0 xnor %g0,%o2,%o0
Lnlop: bcc Lp1 LOC(nlop):
bcc LOC(p1)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Ln1: addx %o4,%o4,%o4 LOC(n1):
addx %o4,%o4,%o4
subcc %o4,%o3,%o1 subcc %o4,%o3,%o1
bcc Lp2 bcc LOC(p2)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Ln2: addx %o4,%o4,%o4 LOC(n2):
addx %o4,%o4,%o4
subcc %o4,%o3,%o1 subcc %o4,%o3,%o1
bcc Lp3 bcc LOC(p3)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Ln3: addx %o4,%o4,%o4 LOC(n3):
addx %o4,%o4,%o4
subcc %o4,%o3,%o1 subcc %o4,%o3,%o1
bcc Lp4 bcc LOC(p4)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Ln4: addx %o4,%o4,%o4 LOC(n4):
addx %o4,%o4,%o4
addcc %g1,-1,%g1 addcc %g1,-1,%g1
bne Lnlop bne LOC(nlop)
subcc %o4,%o3,%o1 subcc %o4,%o3,%o1
bcc Lp5 bcc LOC(p5)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
Ln5: st %o4,[%o0] LOC(n5):
st %o4,[%o0]
retl retl
xnor %g0,%o2,%o0 xnor %g0,%o2,%o0
Largedivisor: LOC(largedivisor):
and %o2,1,%o5 ! %o5 = n0 & 1 and %o2,1,%o5 ! %o5 = n0 & 1
srl %o2,1,%o2 srl %o2,1,%o2
@ -98,89 +107,109 @@ Largedivisor:
srl %o3,1,%g3 ! %g3 = floor(d / 2) srl %o3,1,%g3 ! %g3 = floor(d / 2)
add %g3,%g2,%g3 ! %g3 = ceil(d / 2) add %g3,%g2,%g3 ! %g3 = ceil(d / 2)
b LLp1 b LOC(Lp1)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLplop: bcc LLn1 LOC(Lplop):
bcc LOC(Ln1)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLp1: addx %o1,%o1,%o1 LOC(Lp1):
addx %o1,%o1,%o1
subcc %o1,%g3,%o4 subcc %o1,%g3,%o4
bcc LLn2 bcc LOC(Ln2)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLp2: addx %o1,%o1,%o1 LOC(Lp2):
addx %o1,%o1,%o1
subcc %o1,%g3,%o4 subcc %o1,%g3,%o4
bcc LLn3 bcc LOC(Ln3)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLp3: addx %o1,%o1,%o1 LOC(Lp3):
addx %o1,%o1,%o1
subcc %o1,%g3,%o4 subcc %o1,%g3,%o4
bcc LLn4 bcc LOC(Ln4)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLp4: addx %o1,%o1,%o1 LOC(Lp4):
addx %o1,%o1,%o1
addcc %g1,-1,%g1 addcc %g1,-1,%g1
bne LLplop bne LOC(Lplop)
subcc %o1,%g3,%o4 subcc %o1,%g3,%o4
bcc LLn5 bcc LOC(Ln5)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLp5: add %o1,%o1,%o1 ! << 1 LOC(Lp5):
add %o1,%o1,%o1 ! << 1
tst %g2 tst %g2
bne Oddp bne LOC(Oddp)
add %o5,%o1,%o1 add %o5,%o1,%o1
st %o1,[%o0] st %o1,[%o0]
retl retl
xnor %g0,%o2,%o0 xnor %g0,%o2,%o0
LLnlop: bcc LLp1 LOC(Lnlop):
bcc LOC(Lp1)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLn1: addx %o4,%o4,%o4 LOC(Ln1):
addx %o4,%o4,%o4
subcc %o4,%g3,%o1 subcc %o4,%g3,%o1
bcc LLp2 bcc LOC(Lp2)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLn2: addx %o4,%o4,%o4 LOC(Ln2):
addx %o4,%o4,%o4
subcc %o4,%g3,%o1 subcc %o4,%g3,%o1
bcc LLp3 bcc LOC(Lp3)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLn3: addx %o4,%o4,%o4 LOC(Ln3):
addx %o4,%o4,%o4
subcc %o4,%g3,%o1 subcc %o4,%g3,%o1
bcc LLp4 bcc LOC(Lp4)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLn4: addx %o4,%o4,%o4 LOC(Ln4):
addx %o4,%o4,%o4
addcc %g1,-1,%g1 addcc %g1,-1,%g1
bne LLnlop bne LOC(Lnlop)
subcc %o4,%g3,%o1 subcc %o4,%g3,%o1
bcc LLp5 bcc LOC(Lp5)
addxcc %o2,%o2,%o2 addxcc %o2,%o2,%o2
LLn5: add %o4,%o4,%o4 ! << 1 LOC(Ln5):
add %o4,%o4,%o4 ! << 1
tst %g2 tst %g2
bne Oddn bne LOC(Oddn)
add %o5,%o4,%o4 add %o5,%o4,%o4
st %o4,[%o0] st %o4,[%o0]
retl retl
xnor %g0,%o2,%o0 xnor %g0,%o2,%o0
Oddp: xnor %g0,%o2,%o2 LOC(Oddp):
xnor %g0,%o2,%o2
! q' in %o2. r' in %o1 ! q' in %o2. r' in %o1
addcc %o1,%o2,%o1 addcc %o1,%o2,%o1
bcc LLp6 bcc LOC(Lp6)
addx %o2,0,%o2 addx %o2,0,%o2
sub %o1,%o3,%o1 sub %o1,%o3,%o1
LLp6: subcc %o1,%o3,%g0 LOC(Lp6):
bcs LLp7 subcc %o1,%o3,%g0
bcs LOC(Lp7)
subx %o2,-1,%o2 subx %o2,-1,%o2
sub %o1,%o3,%o1 sub %o1,%o3,%o1
LLp7: st %o1,[%o0] LOC(Lp7):
st %o1,[%o0]
retl retl
mov %o2,%o0 mov %o2,%o0
Oddn: xnor %g0,%o2,%o2 LOC(Oddn):
xnor %g0,%o2,%o2
! q' in %o2. r' in %o4 ! q' in %o2. r' in %o4
addcc %o4,%o2,%o4 addcc %o4,%o2,%o4
bcc LLn6 bcc LOC(Ln6)
addx %o2,0,%o2 addx %o2,0,%o2
sub %o4,%o3,%o4 sub %o4,%o3,%o4
LLn6: subcc %o4,%o3,%g0 LOC(Ln6):
bcs LLn7 subcc %o4,%o3,%g0
bcs LOC(Ln7)
subx %o2,-1,%o2 subx %o2,-1,%o2
sub %o4,%o3,%o4 sub %o4,%o3,%o4
LLn7: st %o4,[%o0] LOC(Ln7):
st %o4,[%o0]
retl retl
mov %o2,%o0 mov %o2,%o0
END(__udiv_qrnnd)

View File

@ -0,0 +1,13 @@
/*
* Sparc v8 has multiply.
*/
#include <sysdep.h>
ENTRY(.umul)
umul %o0, %o1, %o0
retl
rd %y, %o1
END(.umul)

View File

@ -0,0 +1,15 @@
/*
* Sparc v8 has divide.
*/
#include <sysdep.h>
ENTRY(.urem)
wr %g0, 0, %y
udiv %o0, %o1, %o2
umul %o2, %o1, %o2
retl
sub %o0, %o2, %o0
END(.urem)

View File

@ -1,20 +1,20 @@
! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and ! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
! store difference in a third limb vector. ! store difference in a third limb vector.
!
! Copyright (C) 1995, 1996 Free Software Foundation, Inc. ! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library. ! This file is part of the GNU MP Library.
!
! The GNU MP Library is free software; you can redistribute it and/or modify ! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by ! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your ! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version. ! option) any later version.
!
! The GNU MP Library is distributed in the hope that it will be useful, but ! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details. ! License for more details.
!
! You should have received a copy of the GNU Library General Public License ! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to ! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,290 +22,308 @@
! INPUT PARAMETERS ! INPUT PARAMETERS
#define res_ptr %o0 #define RES_PTR %o0
#define s1_ptr %o1 #define S1_PTR %o1
#define s2_ptr %o2 #define S2_PTR %o2
#define size %o3 #define SIZE %o3
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_sub_n)
.align 4 xor S2_PTR,RES_PTR,%g1
.global C_SYMBOL_NAME(__mpn_sub_n)
C_SYMBOL_NAME(__mpn_sub_n):
xor s2_ptr,res_ptr,%g1
andcc %g1,4,%g0 andcc %g1,4,%g0
bne L1 ! branch if alignment differs bne LOC(1) ! branch if alignment differs
nop nop
! ** V1a ** ! ** V1a **
andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0 andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
be L_v1 ! if no, branch be LOC(v1) ! if no, branch
nop nop
/* Add least significant limb separately to align res_ptr and s2_ptr */ /* Add least significant limb separately to align RES_PTR and S2_PTR */
ld [s1_ptr],%g4 ld [S1_PTR],%g4
add s1_ptr,4,s1_ptr add S1_PTR,4,S1_PTR
ld [s2_ptr],%g2 ld [S2_PTR],%g2
add s2_ptr,4,s2_ptr add S2_PTR,4,S2_PTR
add size,-1,size add SIZE,-1,SIZE
subcc %g4,%g2,%o4 subcc %g4,%g2,%o4
st %o4,[res_ptr] st %o4,[RES_PTR]
add res_ptr,4,res_ptr add RES_PTR,4,RES_PTR
L_v1: addx %g0,%g0,%o4 ! save cy in register LOC(v1):
cmp size,2 ! if size < 2 ... addx %g0,%g0,%o4 ! save cy in register
bl Lend2 ! ... branch to tail code cmp SIZE,2 ! if SIZE < 2 ...
bl LOC(end2) ! ... branch to tail code
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
ld [s1_ptr+0],%g4 ld [S1_PTR+0],%g4
addcc size,-10,size addcc SIZE,-10,SIZE
ld [s1_ptr+4],%g1 ld [S1_PTR+4],%g1
ldd [s2_ptr+0],%g2 ldd [S2_PTR+0],%g2
blt Lfin1 blt LOC(fin1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */ /* Add blocks of 8 limbs until less than 8 limbs remain */
Loop1: subxcc %g4,%g2,%o4 LOC(loop1):
ld [s1_ptr+8],%g4
subxcc %g1,%g3,%o5
ld [s1_ptr+12],%g1
ldd [s2_ptr+8],%g2
std %o4,[res_ptr+0]
subxcc %g4,%g2,%o4 subxcc %g4,%g2,%o4
ld [s1_ptr+16],%g4 ld [S1_PTR+8],%g4
subxcc %g1,%g3,%o5 subxcc %g1,%g3,%o5
ld [s1_ptr+20],%g1 ld [S1_PTR+12],%g1
ldd [s2_ptr+16],%g2 ldd [S2_PTR+8],%g2
std %o4,[res_ptr+8] std %o4,[RES_PTR+0]
subxcc %g4,%g2,%o4 subxcc %g4,%g2,%o4
ld [s1_ptr+24],%g4 ld [S1_PTR+16],%g4
subxcc %g1,%g3,%o5 subxcc %g1,%g3,%o5
ld [s1_ptr+28],%g1 ld [S1_PTR+20],%g1
ldd [s2_ptr+24],%g2 ldd [S2_PTR+16],%g2
std %o4,[res_ptr+16] std %o4,[RES_PTR+8]
subxcc %g4,%g2,%o4 subxcc %g4,%g2,%o4
ld [s1_ptr+32],%g4 ld [S1_PTR+24],%g4
subxcc %g1,%g3,%o5 subxcc %g1,%g3,%o5
ld [s1_ptr+36],%g1 ld [S1_PTR+28],%g1
ldd [s2_ptr+32],%g2 ldd [S2_PTR+24],%g2
std %o4,[res_ptr+24] std %o4,[RES_PTR+16]
subxcc %g4,%g2,%o4
ld [S1_PTR+32],%g4
subxcc %g1,%g3,%o5
ld [S1_PTR+36],%g1
ldd [S2_PTR+32],%g2
std %o4,[RES_PTR+24]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-8,size addcc SIZE,-8,SIZE
add s1_ptr,32,s1_ptr add S1_PTR,32,S1_PTR
add s2_ptr,32,s2_ptr add S2_PTR,32,S2_PTR
add res_ptr,32,res_ptr add RES_PTR,32,RES_PTR
bge Loop1 bge LOC(loop1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lfin1: addcc size,8-2,size LOC(fin1):
blt Lend1 addcc SIZE,8-2,SIZE
blt LOC(end1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 2 limbs until less than 2 limbs remain */ /* Add blocks of 2 limbs until less than 2 limbs remain */
Loope1: subxcc %g4,%g2,%o4 LOC(loope1):
ld [s1_ptr+8],%g4 subxcc %g4,%g2,%o4
ld [S1_PTR+8],%g4
subxcc %g1,%g3,%o5 subxcc %g1,%g3,%o5
ld [s1_ptr+12],%g1 ld [S1_PTR+12],%g1
ldd [s2_ptr+8],%g2 ldd [S2_PTR+8],%g2
std %o4,[res_ptr+0] std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size addcc SIZE,-2,SIZE
add s1_ptr,8,s1_ptr add S1_PTR,8,S1_PTR
add s2_ptr,8,s2_ptr add S2_PTR,8,S2_PTR
add res_ptr,8,res_ptr add RES_PTR,8,RES_PTR
bge Loope1 bge LOC(loope1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lend1: subxcc %g4,%g2,%o4 LOC(end1):
subxcc %g4,%g2,%o4
subxcc %g1,%g3,%o5 subxcc %g1,%g3,%o5
std %o4,[res_ptr+0] std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
andcc size,1,%g0 andcc SIZE,1,%g0
be Lret1 be LOC(ret1)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */ /* Add last limb */
ld [s1_ptr+8],%g4 ld [S1_PTR+8],%g4
ld [s2_ptr+8],%g2 ld [S2_PTR+8],%g2
subxcc %g4,%g2,%o4 subxcc %g4,%g2,%o4
st %o4,[res_ptr+8] st %o4,[RES_PTR+8]
Lret1: retl LOC(ret1):
retl
addx %g0,%g0,%o0 ! return carry-out from most sign. limb addx %g0,%g0,%o0 ! return carry-out from most sign. limb
L1: xor s1_ptr,res_ptr,%g1 LOC(1): xor S1_PTR,RES_PTR,%g1
andcc %g1,4,%g0 andcc %g1,4,%g0
bne L2 bne LOC(2)
nop nop
! ** V1b ** ! ** V1b **
andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0 andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
be L_v1b ! if no, branch be LOC(v1b) ! if no, branch
nop nop
/* Add least significant limb separately to align res_ptr and s1_ptr */ /* Add least significant limb separately to align RES_PTR and S1_PTR */
ld [s2_ptr],%g4 ld [S2_PTR],%g4
add s2_ptr,4,s2_ptr add S2_PTR,4,S2_PTR
ld [s1_ptr],%g2 ld [S1_PTR],%g2
add s1_ptr,4,s1_ptr add S1_PTR,4,S1_PTR
add size,-1,size add SIZE,-1,SIZE
subcc %g2,%g4,%o4 subcc %g2,%g4,%o4
st %o4,[res_ptr] st %o4,[RES_PTR]
add res_ptr,4,res_ptr add RES_PTR,4,RES_PTR
L_v1b: addx %g0,%g0,%o4 ! save cy in register LOC(v1b):
cmp size,2 ! if size < 2 ... addx %g0,%g0,%o4 ! save cy in register
bl Lend2 ! ... branch to tail code cmp SIZE,2 ! if SIZE < 2 ...
bl LOC(end2) ! ... branch to tail code
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
ld [s2_ptr+0],%g4 ld [S2_PTR+0],%g4
addcc size,-10,size addcc SIZE,-10,SIZE
ld [s2_ptr+4],%g1 ld [S2_PTR+4],%g1
ldd [s1_ptr+0],%g2 ldd [S1_PTR+0],%g2
blt Lfin1b blt LOC(fin1b)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */ /* Add blocks of 8 limbs until less than 8 limbs remain */
Loop1b: subxcc %g2,%g4,%o4 LOC(loop1b):
ld [s2_ptr+8],%g4
subxcc %g3,%g1,%o5
ld [s2_ptr+12],%g1
ldd [s1_ptr+8],%g2
std %o4,[res_ptr+0]
subxcc %g2,%g4,%o4 subxcc %g2,%g4,%o4
ld [s2_ptr+16],%g4 ld [S2_PTR+8],%g4
subxcc %g3,%g1,%o5 subxcc %g3,%g1,%o5
ld [s2_ptr+20],%g1 ld [S2_PTR+12],%g1
ldd [s1_ptr+16],%g2 ldd [S1_PTR+8],%g2
std %o4,[res_ptr+8] std %o4,[RES_PTR+0]
subxcc %g2,%g4,%o4 subxcc %g2,%g4,%o4
ld [s2_ptr+24],%g4 ld [S2_PTR+16],%g4
subxcc %g3,%g1,%o5 subxcc %g3,%g1,%o5
ld [s2_ptr+28],%g1 ld [S2_PTR+20],%g1
ldd [s1_ptr+24],%g2 ldd [S1_PTR+16],%g2
std %o4,[res_ptr+16] std %o4,[RES_PTR+8]
subxcc %g2,%g4,%o4 subxcc %g2,%g4,%o4
ld [s2_ptr+32],%g4 ld [S2_PTR+24],%g4
subxcc %g3,%g1,%o5 subxcc %g3,%g1,%o5
ld [s2_ptr+36],%g1 ld [S2_PTR+28],%g1
ldd [s1_ptr+32],%g2 ldd [S1_PTR+24],%g2
std %o4,[res_ptr+24] std %o4,[RES_PTR+16]
subxcc %g2,%g4,%o4
ld [S2_PTR+32],%g4
subxcc %g3,%g1,%o5
ld [S2_PTR+36],%g1
ldd [S1_PTR+32],%g2
std %o4,[RES_PTR+24]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-8,size addcc SIZE,-8,SIZE
add s1_ptr,32,s1_ptr add S1_PTR,32,S1_PTR
add s2_ptr,32,s2_ptr add S2_PTR,32,S2_PTR
add res_ptr,32,res_ptr add RES_PTR,32,RES_PTR
bge Loop1b bge LOC(loop1b)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lfin1b: addcc size,8-2,size LOC(fin1b):
blt Lend1b addcc SIZE,8-2,SIZE
blt LOC(end1b)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 2 limbs until less than 2 limbs remain */ /* Add blocks of 2 limbs until less than 2 limbs remain */
Loope1b:subxcc %g2,%g4,%o4 LOC(loope1b):
ld [s2_ptr+8],%g4 subxcc %g2,%g4,%o4
ld [S2_PTR+8],%g4
subxcc %g3,%g1,%o5 subxcc %g3,%g1,%o5
ld [s2_ptr+12],%g1 ld [S2_PTR+12],%g1
ldd [s1_ptr+8],%g2 ldd [S1_PTR+8],%g2
std %o4,[res_ptr+0] std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size addcc SIZE,-2,SIZE
add s1_ptr,8,s1_ptr add S1_PTR,8,S1_PTR
add s2_ptr,8,s2_ptr add S2_PTR,8,S2_PTR
add res_ptr,8,res_ptr add RES_PTR,8,RES_PTR
bge Loope1b bge LOC(loope1b)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lend1b: subxcc %g2,%g4,%o4 LOC(end1b):
subxcc %g2,%g4,%o4
subxcc %g3,%g1,%o5 subxcc %g3,%g1,%o5
std %o4,[res_ptr+0] std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
andcc size,1,%g0 andcc SIZE,1,%g0
be Lret1b be LOC(ret1b)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */ /* Add last limb */
ld [s2_ptr+8],%g4 ld [S2_PTR+8],%g4
ld [s1_ptr+8],%g2 ld [S1_PTR+8],%g2
subxcc %g2,%g4,%o4 subxcc %g2,%g4,%o4
st %o4,[res_ptr+8] st %o4,[RES_PTR+8]
Lret1b: retl LOC(ret1b):
retl
addx %g0,%g0,%o0 ! return carry-out from most sign. limb addx %g0,%g0,%o0 ! return carry-out from most sign. limb
! ** V2 ** ! ** V2 **
/* If we come here, the alignment of s1_ptr and res_ptr as well as the /* If we come here, the alignment of S1_PTR and RES_PTR as well as the
alignment of s2_ptr and res_ptr differ. Since there are only two ways alignment of S2_PTR and RES_PTR differ. Since there are only two ways
things can be aligned (that we care about) we now know that the alignment things can be aligned (that we care about) we now know that the alignment
of s1_ptr and s2_ptr are the same. */ of S1_PTR and S2_PTR are the same. */
L2: cmp size,1 LOC(2): cmp SIZE,1
be Ljone be LOC(jone)
nop nop
andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0 andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
be L_v2 ! if no, branch be LOC(v2) ! if no, branch
nop nop
/* Add least significant limb separately to align s1_ptr and s2_ptr */ /* Add least significant limb separately to align S1_PTR and S2_PTR */
ld [s1_ptr],%g4 ld [S1_PTR],%g4
add s1_ptr,4,s1_ptr add S1_PTR,4,S1_PTR
ld [s2_ptr],%g2 ld [S2_PTR],%g2
add s2_ptr,4,s2_ptr add S2_PTR,4,S2_PTR
add size,-1,size add SIZE,-1,SIZE
subcc %g4,%g2,%o4 subcc %g4,%g2,%o4
st %o4,[res_ptr] st %o4,[RES_PTR]
add res_ptr,4,res_ptr add RES_PTR,4,RES_PTR
L_v2: addx %g0,%g0,%o4 ! save cy in register LOC(v2):
addcc size,-8,size addx %g0,%g0,%o4 ! save cy in register
blt Lfin2 addcc SIZE,-8,SIZE
blt LOC(fin2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */ /* Add blocks of 8 limbs until less than 8 limbs remain */
Loop2: ldd [s1_ptr+0],%g2 LOC(loop2):
ldd [s2_ptr+0],%o4 ldd [S1_PTR+0],%g2
ldd [S2_PTR+0],%o4
subxcc %g2,%o4,%g2 subxcc %g2,%o4,%g2
st %g2,[res_ptr+0] st %g2,[RES_PTR+0]
subxcc %g3,%o5,%g3 subxcc %g3,%o5,%g3
st %g3,[res_ptr+4] st %g3,[RES_PTR+4]
ldd [s1_ptr+8],%g2 ldd [S1_PTR+8],%g2
ldd [s2_ptr+8],%o4 ldd [S2_PTR+8],%o4
subxcc %g2,%o4,%g2 subxcc %g2,%o4,%g2
st %g2,[res_ptr+8] st %g2,[RES_PTR+8]
subxcc %g3,%o5,%g3 subxcc %g3,%o5,%g3
st %g3,[res_ptr+12] st %g3,[RES_PTR+12]
ldd [s1_ptr+16],%g2 ldd [S1_PTR+16],%g2
ldd [s2_ptr+16],%o4 ldd [S2_PTR+16],%o4
subxcc %g2,%o4,%g2 subxcc %g2,%o4,%g2
st %g2,[res_ptr+16] st %g2,[RES_PTR+16]
subxcc %g3,%o5,%g3 subxcc %g3,%o5,%g3
st %g3,[res_ptr+20] st %g3,[RES_PTR+20]
ldd [s1_ptr+24],%g2 ldd [S1_PTR+24],%g2
ldd [s2_ptr+24],%o4 ldd [S2_PTR+24],%o4
subxcc %g2,%o4,%g2 subxcc %g2,%o4,%g2
st %g2,[res_ptr+24] st %g2,[RES_PTR+24]
subxcc %g3,%o5,%g3 subxcc %g3,%o5,%g3
st %g3,[res_ptr+28] st %g3,[RES_PTR+28]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-8,size addcc SIZE,-8,SIZE
add s1_ptr,32,s1_ptr add S1_PTR,32,S1_PTR
add s2_ptr,32,s2_ptr add S2_PTR,32,S2_PTR
add res_ptr,32,res_ptr add RES_PTR,32,RES_PTR
bge Loop2 bge LOC(loop2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lfin2: addcc size,8-2,size LOC(fin2):
blt Lend2 addcc SIZE,8-2,SIZE
blt LOC(end2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Loope2: ldd [s1_ptr+0],%g2 LOC(loope2):
ldd [s2_ptr+0],%o4 ldd [S1_PTR+0],%g2
ldd [S2_PTR+0],%o4
subxcc %g2,%o4,%g2 subxcc %g2,%o4,%g2
st %g2,[res_ptr+0] st %g2,[RES_PTR+0]
subxcc %g3,%o5,%g3 subxcc %g3,%o5,%g3
st %g3,[res_ptr+4] st %g3,[RES_PTR+4]
addx %g0,%g0,%o4 ! save cy in register addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size addcc SIZE,-2,SIZE
add s1_ptr,8,s1_ptr add S1_PTR,8,S1_PTR
add s2_ptr,8,s2_ptr add S2_PTR,8,S2_PTR
add res_ptr,8,res_ptr add RES_PTR,8,RES_PTR
bge Loope2 bge LOC(loope2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
Lend2: andcc size,1,%g0 LOC(end2):
be Lret2 andcc SIZE,1,%g0
be LOC(ret2)
subcc %g0,%o4,%g0 ! restore cy subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */ /* Add last limb */
Ljone: ld [s1_ptr],%g4 LOC(jone):
ld [s2_ptr],%g2 ld [S1_PTR],%g4
ld [S2_PTR],%g2
subxcc %g4,%g2,%o4 subxcc %g4,%g2,%o4
st %o4,[res_ptr] st %o4,[RES_PTR]
Lret2: retl LOC(ret2):
retl
addx %g0,%g0,%o0 ! return carry-out from most sign. limb addx %g0,%g0,%o0 ! return carry-out from most sign. limb
END(__mpn_sub_n)

View File

@ -1,20 +1,20 @@
! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract ! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
! the result from a second limb vector. ! the result from a second limb vector.
!
! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. ! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library. ! This file is part of the GNU MP Library.
!
! The GNU MP Library is free software; you can redistribute it and/or modify ! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by ! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your ! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version. ! option) any later version.
!
! The GNU MP Library is distributed in the hope that it will be useful, but ! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details. ! License for more details.
!
! You should have received a copy of the GNU Library General Public License ! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to ! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,17 +22,14 @@
! INPUT PARAMETERS ! INPUT PARAMETERS
! res_ptr o0 ! RES_PTR o0
! s1_ptr o1 ! S1_PTR o1
! size o2 ! SIZE o2
! s2_limb o3 ! S2_LIMB o3
#include "sysdep.h" #include <sysdep.h>
.text ENTRY(__mpn_submul_1)
.align 4
.global C_SYMBOL_NAME(__mpn_submul_1)
C_SYMBOL_NAME(__mpn_submul_1):
! Make S1_PTR and RES_PTR point at the end of their blocks ! Make S1_PTR and RES_PTR point at the end of their blocks
! and put (- 4 x SIZE) in index/loop counter. ! and put (- 4 x SIZE) in index/loop counter.
sll %o2,2,%o2 sll %o2,2,%o2
@ -41,19 +38,19 @@ C_SYMBOL_NAME(__mpn_submul_1):
sub %g0,%o2,%o2 sub %g0,%o2,%o2
cmp %o3,0xfff cmp %o3,0xfff
bgu Large bgu LOC(large)
nop nop
ld [%o1+%o2],%o5 ld [%o1+%o2],%o5
mov 0,%o0 mov 0,%o0
b L0 b LOC(0)
add %o4,-4,%o4 add %o4,-4,%o4
Loop0: LOC(loop0):
subcc %o5,%g1,%g1 subcc %o5,%g1,%g1
ld [%o1+%o2],%o5 ld [%o1+%o2],%o5
addx %o0,%g0,%o0 addx %o0,%g0,%o0
st %g1,[%o4+%o2] st %g1,[%o4+%o2]
L0: wr %g0,%o3,%y LOC(0): wr %g0,%o3,%y
sra %o5,31,%g2 sra %o5,31,%g2
and %o3,%g2,%g2 and %o3,%g2,%g2
andcc %g1,0,%g1 andcc %g1,0,%g1
@ -79,7 +76,7 @@ L0: wr %g0,%o3,%y
addcc %g1,%o0,%g1 addcc %g1,%o0,%g1
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter addcc %o2,4,%o2 ! loop counter
bne Loop0 bne LOC(loop0)
ld [%o4+%o2],%o5 ld [%o4+%o2],%o5
subcc %o5,%g1,%g1 subcc %o5,%g1,%g1
@ -88,17 +85,18 @@ L0: wr %g0,%o3,%y
st %g1,[%o4+%o2] st %g1,[%o4+%o2]
Large: ld [%o1+%o2],%o5 LOC(large):
ld [%o1+%o2],%o5
mov 0,%o0 mov 0,%o0
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0 sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
b L1 b LOC(1)
add %o4,-4,%o4 add %o4,-4,%o4
Loop: LOC(loop):
subcc %o5,%g3,%g3 subcc %o5,%g3,%g3
ld [%o1+%o2],%o5 ld [%o1+%o2],%o5
addx %o0,%g0,%o0 addx %o0,%g0,%o0
st %g3,[%o4+%o2] st %g3,[%o4+%o2]
L1: wr %g0,%o5,%y LOC(1): wr %g0,%o5,%y
and %o5,%g4,%g2 and %o5,%g4,%g2
andcc %g0,%g0,%g1 andcc %g0,%g0,%g1
mulscc %g1,%o3,%g1 mulscc %g1,%o3,%g1
@ -138,10 +136,12 @@ L1: wr %g0,%o5,%y
addcc %g3,%o0,%g3 addcc %g3,%o0,%g3
addx %g2,%g1,%o0 addx %g2,%g1,%o0
addcc %o2,4,%o2 addcc %o2,4,%o2
bne Loop bne LOC(loop)
ld [%o4+%o2],%o5 ld [%o4+%o2],%o5
subcc %o5,%g3,%g3 subcc %o5,%g3,%g3
addx %o0,%g0,%o0 addx %o0,%g0,%o0
retl retl
st %g3,[%o4+%o2] st %g3,[%o4+%o2]
END(__mpn_submul_1)

View File

@ -37,16 +37,8 @@
#include "sysdep.h" #include <sysdep.h>
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sys/trap.h> #include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
ENTRY(.udiv) ENTRY(.udiv)
@ -63,11 +55,11 @@ ENTRY(.udiv)
1: 1:
cmp %o3, %o5 ! if %o1 exceeds %o0, done cmp %o3, %o5 ! if %o1 exceeds %o0, done
blu Lgot_result ! (and algorithm fails otherwise) blu LOC(got_result) ! (and algorithm fails otherwise)
clr %o2 clr %o2
sethi %hi(1 << (32 - 4 - 1)), %g1 sethi %hi(1 << (32 - 4 - 1)), %g1
cmp %o3, %g1 cmp %o3, %g1
blu Lnot_really_big blu LOC(not_really_big)
clr %o4 clr %o4
! Here the dividend is >= 2**(31-N) or so. We must be careful here, ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
@ -78,15 +70,15 @@ ENTRY(.udiv)
1: 1:
cmp %o5, %g1 cmp %o5, %g1
bgeu 3f bgeu 3f
mov 1, %g7 mov 1, %g2
sll %o5, 4, %o5 sll %o5, 4, %o5
b 1b b 1b
add %o4, 1, %o4 add %o4, 1, %o4
! Now compute %g7. ! Now compute %g2.
2: addcc %o5, %o5, %o5 2: addcc %o5, %o5, %o5
bcc Lnot_too_big bcc LOC(not_too_big)
add %g7, 1, %g7 add %g2, 1, %g2
! We get here if the %o1 overflowed while shifting. ! We get here if the %o1 overflowed while shifting.
! This means that %o3 has the high-order bit set. ! This means that %o3 has the high-order bit set.
@ -94,20 +86,20 @@ ENTRY(.udiv)
sll %g1, 4, %g1 ! high order bit sll %g1, 4, %g1 ! high order bit
srl %o5, 1, %o5 ! rest of %o5 srl %o5, 1, %o5 ! rest of %o5
add %o5, %g1, %o5 add %o5, %g1, %o5
b Ldo_single_div b LOC(do_single_div)
sub %g7, 1, %g7 sub %g2, 1, %g2
Lnot_too_big: LOC(not_too_big):
3: cmp %o5, %o3 3: cmp %o5, %o3
blu 2b blu 2b
nop nop
be Ldo_single_div be LOC(do_single_div)
nop nop
/* NB: these are commented out in the V8-Sparc manual as well */ /* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */ /* (I do not understand this) */
! %o5 > %o3: went too far: back up 1 step ! %o5 > %o3: went too far: back up 1 step
! srl %o5, 1, %o5 ! srl %o5, 1, %o5
! dec %g7 ! dec %g2
! do single-bit divide steps ! do single-bit divide steps
! !
! We have to be careful here. We know that %o3 >= %o5, so we can do the ! We have to be careful here. We know that %o3 >= %o5, so we can do the
@ -116,15 +108,15 @@ ENTRY(.udiv)
! order bit set in the first step, just falling into the regular ! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around. ! division loop will mess up the first time around.
! So we unroll slightly... ! So we unroll slightly...
Ldo_single_div: LOC(do_single_div):
subcc %g7, 1, %g7 subcc %g2, 1, %g2
bl Lend_regular_divide bl LOC(end_regular_divide)
nop nop
sub %o3, %o5, %o3 sub %o3, %o5, %o3
mov 1, %o2 mov 1, %o2
b Lend_single_divloop b LOC(end_single_divloop)
nop nop
Lsingle_divloop: LOC(single_divloop):
sll %o2, 1, %o2 sll %o2, 1, %o2
bl 1f bl 1f
srl %o5, 1, %o5 srl %o5, 1, %o5
@ -136,217 +128,219 @@ ENTRY(.udiv)
add %o3, %o5, %o3 add %o3, %o5, %o3
sub %o2, 1, %o2 sub %o2, 1, %o2
2: 2:
Lend_single_divloop: LOC(end_single_divloop):
subcc %g7, 1, %g7 subcc %g2, 1, %g2
bge Lsingle_divloop bge LOC(single_divloop)
tst %o3 tst %o3
b,a Lend_regular_divide b,a LOC(end_regular_divide)
Lnot_really_big: LOC(not_really_big):
1: 1:
sll %o5, 4, %o5 sll %o5, 4, %o5
cmp %o5, %o3 cmp %o5, %o3
bleu 1b bleu 1b
addcc %o4, 1, %o4 addcc %o4, 1, %o4
be Lgot_result be LOC(got_result)
sub %o4, 1, %o4 sub %o4, 1, %o4
tst %o3 ! set up for initial iteration tst %o3 ! set up for initial iteration
Ldivloop: LOC(divloop):
sll %o2, 4, %o2 sll %o2, 4, %o2
! depth 1, accumulated bits 0 ! depth 1, accumulated bits 0
bl L.1.16 bl LOC(1.16)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 2, accumulated bits 1 ! depth 2, accumulated bits 1
bl L.2.17 bl LOC(2.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 3, accumulated bits 3 ! depth 3, accumulated bits 3
bl L.3.19 bl LOC(3.19)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits 7 ! depth 4, accumulated bits 7
bl L.4.23 bl LOC(4.23)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (7*2+1), %o2 add %o2, (7*2+1), %o2
L.4.23: LOC(4.23):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (7*2-1), %o2 add %o2, (7*2-1), %o2
L.3.19: LOC(3.19):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits 5 ! depth 4, accumulated bits 5
bl L.4.21 bl LOC(4.21)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (5*2+1), %o2 add %o2, (5*2+1), %o2
L.4.21: LOC(4.21):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (5*2-1), %o2 add %o2, (5*2-1), %o2
L.2.17: LOC(2.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 3, accumulated bits 1 ! depth 3, accumulated bits 1
bl L.3.17 bl LOC(3.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits 3 ! depth 4, accumulated bits 3
bl L.4.19 bl LOC(4.19)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (3*2+1), %o2 add %o2, (3*2+1), %o2
L.4.19: LOC(4.19):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (3*2-1), %o2 add %o2, (3*2-1), %o2
L.3.17: LOC(3.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits 1 ! depth 4, accumulated bits 1
bl L.4.17 bl LOC(4.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (1*2+1), %o2 add %o2, (1*2+1), %o2
L.4.17: LOC(4.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (1*2-1), %o2 add %o2, (1*2-1), %o2
L.1.16: LOC(1.16):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 2, accumulated bits -1 ! depth 2, accumulated bits -1
bl L.2.15 bl LOC(2.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 3, accumulated bits -1 ! depth 3, accumulated bits -1
bl L.3.15 bl LOC(3.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits -1 ! depth 4, accumulated bits -1
bl L.4.15 bl LOC(4.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-1*2+1), %o2 add %o2, (-1*2+1), %o2
L.4.15: LOC(4.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-1*2-1), %o2 add %o2, (-1*2-1), %o2
L.3.15: LOC(3.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits -3 ! depth 4, accumulated bits -3
bl L.4.13 bl LOC(4.13)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-3*2+1), %o2 add %o2, (-3*2+1), %o2
L.4.13: LOC(4.13):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-3*2-1), %o2 add %o2, (-3*2-1), %o2
L.2.15: LOC(2.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 3, accumulated bits -3 ! depth 3, accumulated bits -3
bl L.3.13 bl LOC(3.13)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits -5 ! depth 4, accumulated bits -5
bl L.4.11 bl LOC(4.11)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-5*2+1), %o2 add %o2, (-5*2+1), %o2
L.4.11: LOC(4.11):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-5*2-1), %o2 add %o2, (-5*2-1), %o2
L.3.13: LOC(3.13):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits -7 ! depth 4, accumulated bits -7
bl L.4.9 bl LOC(4.9)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-7*2+1), %o2 add %o2, (-7*2+1), %o2
L.4.9: LOC(4.9):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-7*2-1), %o2 add %o2, (-7*2-1), %o2
9: 9:
Lend_regular_divide: LOC(end_regular_divide):
subcc %o4, 1, %o4 subcc %o4, 1, %o4
bge Ldivloop bge LOC(divloop)
tst %o3 tst %o3
bl,a Lgot_result bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!) ! non-restoring fixup here (one instruction only!)
sub %o2, 1, %o2 sub %o2, 1, %o2
Lgot_result: LOC(got_result):
retl retl
mov %o2, %o0 mov %o2, %o0
END(.udiv)

View File

@ -1,50 +1,52 @@
! SPARC __udiv_qrnnd division support, used from longlong.h. ! SPARC __udiv_qrnnd division support, used from longlong.h.
!
! Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc. ! Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library. ! This file is part of the GNU MP Library.
!
! The GNU MP Library is free software; you can redistribute it and/or modify ! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by ! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your ! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version. ! option) any later version.
!
! The GNU MP Library is distributed in the hope that it will be useful, but ! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details. ! License for more details.
!
! You should have received a copy of the GNU Library General Public License ! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to ! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
!
! Added PIC support - May/96, Miguel de Icaza ! Added PIC support - May/96, Miguel de Icaza
!
! INPUT PARAMETERS ! INPUT PARAMETERS
! rem_ptr i0 ! rem_ptr i0
! n1 i1 ! n1 i1
! n0 i2 ! n0 i2
! d i3 ! d i3
#include "sysdep.h" #include <sysdep.h>
#undef ret /* Kludge for glibc */ #undef ret /* Kludge for glibc */
#ifdef PIC
.text .text
#else
.section .rodata,#alloc
#endif
.align 8 .align 8
.type two_to_32,@object .type two_to_32,@object
.size two_to_32,8
two_to_32: two_to_32:
.double 0r4294967296 .double 0r4294967296
.size two_to_32,8
.type two_to_31,@object .type two_to_31,@object
.size two_to_31,8
two_to_31: two_to_31:
.double 0r2147483648 .double 0r2147483648
.size two_to_31,8
.align 4 .text
.global __udiv_qrnnd
.type __udiv_qrnnd,@function
ENTRY(__udiv_qrnnd) ENTRY(__udiv_qrnnd)
!#PROLOGUE# 0 !#PROLOGUE# 0
save %sp,-104,%sp save %sp,-104,%sp
@ -52,57 +54,58 @@ ENTRY(__udiv_qrnnd)
st %i1,[%fp-8] st %i1,[%fp-8]
ld [%fp-8],%f10 ld [%fp-8],%f10
#ifdef PIC #ifdef PIC
.Lbase: call 1f LOC(base):
call 1f
fitod %f10,%f4 fitod %f10,%f4
1: ldd [%o7-(.Lbase-two_to_32)],%f8 1: ldd [%o7-(LOC(base)-two_to_32)],%f8
#else #else
sethi %hi(two_to_32),%o7 sethi %hi(two_to_32),%o7
fitod %f10,%f4 fitod %f10,%f4
ldd [%o7+%lo(two_to_32)],%f8 ldd [%o7+%lo(two_to_32)],%f8
#endif #endif
cmp %i1,0 cmp %i1,0
bge L248 bge LOC(248)
mov %i0,%i5 mov %i0,%i5
faddd %f4,%f8,%f4 faddd %f4,%f8,%f4
.L248: LOC(248):
st %i2,[%fp-8] st %i2,[%fp-8]
ld [%fp-8],%f10 ld [%fp-8],%f10
fmuld %f4,%f8,%f6 fmuld %f4,%f8,%f6
cmp %i2,0 cmp %i2,0
bge L249 bge LOC(249)
fitod %f10,%f2 fitod %f10,%f2
faddd %f2,%f8,%f2 faddd %f2,%f8,%f2
.L249: LOC(249):
st %i3,[%fp-8] st %i3,[%fp-8]
faddd %f6,%f2,%f2 faddd %f6,%f2,%f2
ld [%fp-8],%f10 ld [%fp-8],%f10
cmp %i3,0 cmp %i3,0
bge L250 bge LOC(250)
fitod %f10,%f4 fitod %f10,%f4
faddd %f4,%f8,%f4 faddd %f4,%f8,%f4
.L250: LOC(250):
fdivd %f2,%f4,%f2 fdivd %f2,%f4,%f2
#ifdef PIC #ifdef PIC
ldd [%o7-(.Lbase-two_to_31)],%f4 ldd [%o7-(LOC(base)-two_to_31)],%f4
#else #else
sethi %hi(two_to_31),%o7 sethi %hi(two_to_31),%o7
ldd [%o7+%lo(two_to_31)],%f4 ldd [%o7+%lo(two_to_31)],%f4
#endif #endif
fcmped %f2,%f4 fcmped %f2,%f4
nop nop
fbge,a L251 fbge,a LOC(251)
fsubd %f2,%f4,%f2 fsubd %f2,%f4,%f2
fdtoi %f2,%f2 fdtoi %f2,%f2
st %f2,[%fp-8] st %f2,[%fp-8]
b L252 b LOC(252)
ld [%fp-8],%i4 ld [%fp-8],%i4
.L251: LOC(251):
fdtoi %f2,%f2 fdtoi %f2,%f2
st %f2,[%fp-8] st %f2,[%fp-8]
ld [%fp-8],%i4 ld [%fp-8],%i4
sethi %hi(-2147483648),%g2 sethi %hi(-2147483648),%g2
xor %i4,%g2,%i4 xor %i4,%g2,%i4
.L252: LOC(252):
wr %g0,%i4,%y wr %g0,%i4,%y
sra %i3,31,%g2 sra %i3,31,%g2
and %i4,%g2,%g2 and %i4,%g2,%g2
@ -144,7 +147,7 @@ ENTRY(__udiv_qrnnd)
rd %y,%g3 rd %y,%g3
subcc %i2,%g3,%o7 subcc %i2,%g3,%o7
subxcc %i1,%i0,%g0 subxcc %i1,%i0,%g0
be L253 be LOC(253)
cmp %o7,%i3 cmp %o7,%i3
add %i4,-1,%i0 add %i4,-1,%i0
@ -152,14 +155,14 @@ ENTRY(__udiv_qrnnd)
st %o7,[%i5] st %o7,[%i5]
ret ret
restore restore
.L253: LOC(253):
blu L246 blu LOC(246)
mov %i4,%i0 mov %i4,%i0
add %i4,1,%i0 add %i4,1,%i0
sub %o7,%i3,%o7 sub %o7,%i3,%o7
.L246: LOC(246):
st %o7,[%i5] st %o7,[%i5]
ret ret
restore restore
.size __udiv_qrnnd, .-__udiv_qrnnd END(__udiv_qrnnd)

View File

@ -14,13 +14,14 @@
* bnz overflow (or tnz) * bnz overflow (or tnz)
*/ */
#include "DEFS.h" #include <sysdep.h>
FUNC(.umul)
ENTRY(.umul)
or %o0, %o1, %o4 or %o0, %o1, %o4
mov %o0, %y ! multiplier -> Y mov %o0, %y ! multiplier -> Y
andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
be Lmul_shortway ! if zero, can do it the short way be LOC(mul_shortway) ! if zero, can do it the short way
andcc %g0, %g0, %o4 ! zero the partial product and clear N and V andcc %g0, %g0, %o4 ! zero the partial product; clear N & V
/* /*
* Long multiply. 32 steps, followed by a final shift step. * Long multiply. 32 steps, followed by a final shift step.
@ -59,7 +60,6 @@ FUNC(.umul)
mulscc %o4, %o1, %o4 ! 32 mulscc %o4, %o1, %o4 ! 32
mulscc %o4, %g0, %o4 ! final shift mulscc %o4, %g0, %o4 ! final shift
/* /*
* Normally, with the shift-and-add approach, if both numbers are * Normally, with the shift-and-add approach, if both numbers are
* positive you get the correct result. With 32-bit two's-complement * positive you get the correct result. With 32-bit two's-complement
@ -97,20 +97,20 @@ FUNC(.umul)
#if 0 #if 0
tst %o1 tst %o1
bl,a 1f ! if %o1 < 0 (high order bit = 1), bl,a 1f ! if %o1 < 0 (high order bit = 1),
add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half) add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half)
1: rd %y, %o0 ! get lower half of product 1: rd %y, %o0 ! get lower half of product
retl retl
addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0 addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0
#else #else
/* Faster code from tege@sics.se. */ /* Faster code from tege@sics.se. */
sra %o1, 31, %o2 ! make mask from sign bit sra %o1, 31, %o2 ! make mask from sign bit
and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1 and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1
rd %y, %o0 ! get lower half of product rd %y, %o0 ! get lower half of product
retl retl
addcc %o4, %o2, %o1 ! add compensation and put upper half in place addcc %o4, %o2, %o1 ! add compensation and put upper half in place
#endif #endif
Lmul_shortway: LOC(mul_shortway):
/* /*
* Short multiply. 12 steps, followed by a final shift step. * Short multiply. 12 steps, followed by a final shift step.
* The resulting bits are off by 12 and (32-12) = 20 bit positions, * The resulting bits are off by 12 and (32-12) = 20 bit positions,
@ -150,4 +150,6 @@ Lmul_shortway:
srl %o5, 20, %o5 ! shift low bits right 20 srl %o5, 20, %o5 ! shift low bits right 20
or %o5, %o0, %o0 or %o5, %o0, %o0
retl retl
addcc %g0, %g0, %o1 ! %o1 = zero, and set Z addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
END(.umul)

View File

@ -37,16 +37,8 @@
#include "sysdep.h" #include <sysdep.h>
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sys/trap.h> #include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
ENTRY(.urem) ENTRY(.urem)
@ -63,11 +55,11 @@ ENTRY(.urem)
1: 1:
cmp %o3, %o5 ! if %o1 exceeds %o0, done cmp %o3, %o5 ! if %o1 exceeds %o0, done
blu Lgot_result ! (and algorithm fails otherwise) blu LOC(got_result) ! (and algorithm fails otherwise)
clr %o2 clr %o2
sethi %hi(1 << (32 - 4 - 1)), %g1 sethi %hi(1 << (32 - 4 - 1)), %g1
cmp %o3, %g1 cmp %o3, %g1
blu Lnot_really_big blu LOC(not_really_big)
clr %o4 clr %o4
! Here the dividend is >= 2**(31-N) or so. We must be careful here, ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
@ -78,15 +70,15 @@ ENTRY(.urem)
1: 1:
cmp %o5, %g1 cmp %o5, %g1
bgeu 3f bgeu 3f
mov 1, %g7 mov 1, %g2
sll %o5, 4, %o5 sll %o5, 4, %o5
b 1b b 1b
add %o4, 1, %o4 add %o4, 1, %o4
! Now compute %g7. ! Now compute %g2.
2: addcc %o5, %o5, %o5 2: addcc %o5, %o5, %o5
bcc Lnot_too_big bcc LOC(not_too_big)
add %g7, 1, %g7 add %g2, 1, %g2
! We get here if the %o1 overflowed while shifting. ! We get here if the %o1 overflowed while shifting.
! This means that %o3 has the high-order bit set. ! This means that %o3 has the high-order bit set.
@ -94,20 +86,20 @@ ENTRY(.urem)
sll %g1, 4, %g1 ! high order bit sll %g1, 4, %g1 ! high order bit
srl %o5, 1, %o5 ! rest of %o5 srl %o5, 1, %o5 ! rest of %o5
add %o5, %g1, %o5 add %o5, %g1, %o5
b Ldo_single_div b LOC(do_single_div)
sub %g7, 1, %g7 sub %g2, 1, %g2
Lnot_too_big: LOC(not_too_big):
3: cmp %o5, %o3 3: cmp %o5, %o3
blu 2b blu 2b
nop nop
be Ldo_single_div be LOC(do_single_div)
nop nop
/* NB: these are commented out in the V8-Sparc manual as well */ /* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */ /* (I do not understand this) */
! %o5 > %o3: went too far: back up 1 step ! %o5 > %o3: went too far: back up 1 step
! srl %o5, 1, %o5 ! srl %o5, 1, %o5
! dec %g7 ! dec %g2
! do single-bit divide steps ! do single-bit divide steps
! !
! We have to be careful here. We know that %o3 >= %o5, so we can do the ! We have to be careful here. We know that %o3 >= %o5, so we can do the
@ -116,15 +108,15 @@ ENTRY(.urem)
! order bit set in the first step, just falling into the regular ! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around. ! division loop will mess up the first time around.
! So we unroll slightly... ! So we unroll slightly...
Ldo_single_div: LOC(do_single_div):
subcc %g7, 1, %g7 subcc %g2, 1, %g2
bl Lend_regular_divide bl LOC(end_regular_divide)
nop nop
sub %o3, %o5, %o3 sub %o3, %o5, %o3
mov 1, %o2 mov 1, %o2
b Lend_single_divloop b LOC(end_single_divloop)
nop nop
Lsingle_divloop: LOC(single_divloop):
sll %o2, 1, %o2 sll %o2, 1, %o2
bl 1f bl 1f
srl %o5, 1, %o5 srl %o5, 1, %o5
@ -136,217 +128,219 @@ ENTRY(.urem)
add %o3, %o5, %o3 add %o3, %o5, %o3
sub %o2, 1, %o2 sub %o2, 1, %o2
2: 2:
Lend_single_divloop: LOC(end_single_divloop):
subcc %g7, 1, %g7 subcc %g2, 1, %g2
bge Lsingle_divloop bge LOC(single_divloop)
tst %o3 tst %o3
b,a Lend_regular_divide b,a LOC(end_regular_divide)
Lnot_really_big: LOC(not_really_big):
1: 1:
sll %o5, 4, %o5 sll %o5, 4, %o5
cmp %o5, %o3 cmp %o5, %o3
bleu 1b bleu 1b
addcc %o4, 1, %o4 addcc %o4, 1, %o4
be Lgot_result be LOC(got_result)
sub %o4, 1, %o4 sub %o4, 1, %o4
tst %o3 ! set up for initial iteration tst %o3 ! set up for initial iteration
Ldivloop: LOC(divloop):
sll %o2, 4, %o2 sll %o2, 4, %o2
! depth 1, accumulated bits 0 ! depth 1, accumulated bits 0
bl L.1.16 bl LOC(1.16)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 2, accumulated bits 1 ! depth 2, accumulated bits 1
bl L.2.17 bl LOC(2.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 3, accumulated bits 3 ! depth 3, accumulated bits 3
bl L.3.19 bl LOC(3.19)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits 7 ! depth 4, accumulated bits 7
bl L.4.23 bl LOC(4.23)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (7*2+1), %o2 add %o2, (7*2+1), %o2
L.4.23: LOC(4.23):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (7*2-1), %o2 add %o2, (7*2-1), %o2
L.3.19: LOC(3.19):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits 5 ! depth 4, accumulated bits 5
bl L.4.21 bl LOC(4.21)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (5*2+1), %o2 add %o2, (5*2+1), %o2
L.4.21: LOC(4.21):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (5*2-1), %o2 add %o2, (5*2-1), %o2
L.2.17: LOC(2.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 3, accumulated bits 1 ! depth 3, accumulated bits 1
bl L.3.17 bl LOC(3.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits 3 ! depth 4, accumulated bits 3
bl L.4.19 bl LOC(4.19)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (3*2+1), %o2 add %o2, (3*2+1), %o2
L.4.19: LOC(4.19):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (3*2-1), %o2 add %o2, (3*2-1), %o2
L.3.17: LOC(3.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits 1 ! depth 4, accumulated bits 1
bl L.4.17 bl LOC(4.17)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (1*2+1), %o2 add %o2, (1*2+1), %o2
L.4.17: LOC(4.17):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (1*2-1), %o2 add %o2, (1*2-1), %o2
L.1.16: LOC(1.16):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 2, accumulated bits -1 ! depth 2, accumulated bits -1
bl L.2.15 bl LOC(2.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 3, accumulated bits -1 ! depth 3, accumulated bits -1
bl L.3.15 bl LOC(3.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits -1 ! depth 4, accumulated bits -1
bl L.4.15 bl LOC(4.15)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-1*2+1), %o2 add %o2, (-1*2+1), %o2
L.4.15: LOC(4.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-1*2-1), %o2 add %o2, (-1*2-1), %o2
L.3.15: LOC(3.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits -3 ! depth 4, accumulated bits -3
bl L.4.13 bl LOC(4.13)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-3*2+1), %o2 add %o2, (-3*2+1), %o2
L.4.13: LOC(4.13):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-3*2-1), %o2 add %o2, (-3*2-1), %o2
L.2.15: LOC(2.15):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 3, accumulated bits -3 ! depth 3, accumulated bits -3
bl L.3.13 bl LOC(3.13)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
! depth 4, accumulated bits -5 ! depth 4, accumulated bits -5
bl L.4.11 bl LOC(4.11)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-5*2+1), %o2 add %o2, (-5*2+1), %o2
L.4.11: LOC(4.11):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-5*2-1), %o2 add %o2, (-5*2-1), %o2
L.3.13: LOC(3.13):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
! depth 4, accumulated bits -7 ! depth 4, accumulated bits -7
bl L.4.9 bl LOC(4.9)
srl %o5,1,%o5 srl %o5,1,%o5
! remainder is positive ! remainder is positive
subcc %o3,%o5,%o3 subcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-7*2+1), %o2 add %o2, (-7*2+1), %o2
L.4.9: LOC(4.9):
! remainder is negative ! remainder is negative
addcc %o3,%o5,%o3 addcc %o3,%o5,%o3
b 9f b 9f
add %o2, (-7*2-1), %o2 add %o2, (-7*2-1), %o2
9: 9:
Lend_regular_divide: LOC(end_regular_divide):
subcc %o4, 1, %o4 subcc %o4, 1, %o4
bge Ldivloop bge LOC(divloop)
tst %o3 tst %o3
bl,a Lgot_result bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!) ! non-restoring fixup here (one instruction only!)
add %o3, %o1, %o3 add %o3, %o1, %o3
Lgot_result: LOC(got_result):
retl retl
mov %o3, %o0 mov %o3, %o0
END(.urem)

View File

@ -220,6 +220,13 @@ elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc)
/* The SPARC overlaps DT_RELA and DT_PLTREL. */ /* The SPARC overlaps DT_RELA and DT_PLTREL. */
#define ELF_MACHINE_PLTREL_OVERLAP 1 #define ELF_MACHINE_PLTREL_OVERLAP 1
/* The return value from dl-runtime's fixup, if it should be special. */
#define ELF_FIXUP_RETURN_VALUE(map, result) \
((map)->l_info[DT_SPARC(PLTFMT)] \
&& (map)->l_info[DT_SPARC(PLTFMT)]->d_un.d_val == 2 \
? (result) + (map)->l_info[DT_PLTGOT]->d_un.d_ptr + (map)->l_addr \
: (result))
/* Set up the loaded object described by L so its unrelocated PLT /* Set up the loaded object described by L so its unrelocated PLT
entries will jump to the on-demand fixup code in dl-runtime.c. */ entries will jump to the on-demand fixup code in dl-runtime.c. */
@ -232,10 +239,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
if (l->l_info[DT_JMPREL] && lazy) if (l->l_info[DT_JMPREL] && lazy)
{ {
got = (Elf64_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr); got = (Elf64_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
got[1] = (Elf64_Addr) l; /* Identify this shared object. */
/* This function will get called to fix up the GOT entry indicated by /* This function will get called to fix up the GOT entry indicated by
the offset on the stack, and then jump to the resolved address. */ the offset on the stack, and then jump to the resolved address. */
got[2] = (Elf64_Addr) &_dl_runtime_resolve; got[1] = (Elf64_Addr) &_dl_runtime_resolve;
got[2] = (Elf64_Addr) l; /* Identify this shared object. */
} }
return lazy; return lazy;
@ -248,9 +255,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
.type _dl_runtime_resolve, @function .type _dl_runtime_resolve, @function
_dl_runtime_resolve: _dl_runtime_resolve:
save %sp, -160, %sp save %sp, -160, %sp
mov %g5, %o0 mov %g1, %o0
call fixup call fixup
mov %g6, %o1 mov %g2, %o1
jmp %o0 jmp %o0
restore restore
.size _dl_runtime_resolve, .-_dl_runtime_resolve .size _dl_runtime_resolve, .-_dl_runtime_resolve

View File

@ -41,13 +41,11 @@
/* Now two recommended cw */ /* Now two recommended cw */
/* Linux default: /* Linux and IEEE default:
- extended precision - extended precision
- rounding to nearest - rounding to nearest
- no exceptions */ - no exceptions */
#define _FPU_DEFAULT 0x0 #define _FPU_DEFAULT 0x0
/* IEEE: same as above */
#define _FPU_IEEE 0x0 #define _FPU_IEEE 0x0
/* Type of the control word. */ /* Type of the control word. */

View File

@ -311,11 +311,11 @@ static inline void set_segment(
/* Now, reload all segment registers so the limit takes effect. */ /* Now, reload all segment registers so the limit takes effect. */
asm volatile( "movw %%ds,%0 ; movw %0,%%ds asm volatile( "movw %%ds,%0 ; movw %0,%%ds\n"
movw %%es,%0 ; movw %0,%%es "movw %%es,%0 ; movw %0,%%es\n"
movw %%fs,%0 ; movw %0,%%fs "movw %%fs,%0 ; movw %0,%%fs\n"
movw %%gs,%0 ; movw %0,%%gs "movw %%gs,%0 ; movw %0,%%gs\n"
movw %%ss,%0 ; movw %0,%%ss" "movw %%ss,%0 ; movw %0,%%ss"
: "=r" (tmp_segment) : "=r" (tmp_segment)
: "0" (tmp_segment) : "0" (tmp_segment)
); );

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1994, 1996 Free Software Foundation, Inc. /* Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
On-Line Applications Research Corporation. On-Line Applications Research Corporation.
@ -157,10 +157,10 @@ struct i80960ca_ctltbl {
#define clear_intr( xint ) \ #define clear_intr( xint ) \
{ register unsigned32 _xint=(xint); \ { register unsigned32 _xint=(xint); \
asm volatile( "loop_til_cleared: asm volatile( "loop_til_cleared:" \
clrbit %0,sf0,sf0 ; \ " clrbit %0,sf0,sf0 ;" \
bbs %0,sf0,loop_til_cleared" \ " bbs %0,sf0,loop_til_cleared" \
: "=d" (_xint) : "0" (_xint) ); \ : "=d" (_xint) : "0" (_xint) ); \
} }
#define reload_ctl_group( group ) \ #define reload_ctl_group( group ) \

View File

@ -50,7 +50,7 @@ static void
init (int argc, char **argv, char **envp) init (int argc, char **argv, char **envp)
{ {
extern int __personality (int); extern int __personality (int);
extern void __getopt_clean_environment (void); extern void __getopt_clean_environment (char **);
/* We must not call `personality' twice. */ /* We must not call `personality' twice. */
if (!__libc_multiple_libcs) if (!__libc_multiple_libcs)
@ -74,7 +74,7 @@ init (int argc, char **argv, char **envp)
__libc_init (argc, argv, envp); __libc_init (argc, argv, envp);
/* This is a hack to make the special getopt in GNU libc working. */ /* This is a hack to make the special getopt in GNU libc working. */
__getopt_clean_environment (); __getopt_clean_environment (envp);
#ifdef PIC #ifdef PIC
__libc_global_ctors (); __libc_global_ctors ();

View File

@ -74,24 +74,19 @@ ENTRY(____sparc_signal_trampoline)
1: 1:
#ifdef PIC #ifdef PIC
/* Save return address */ /* Save return address */
mov %o7,%o4 mov %o7,%o5
___sxx: 11: call 12f
call ___syy sethi %hi(_GLOBAL_OFFSET_TABLE_-(11b-.)),%o4
nop 12: or %o5,%lo(_GLOBAL_OFFSET_TABLE_-(11b-.)),%o4
___syy: add %o7,%o4,%o4
sethi %hi(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
or %o5,%lo(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
add %o7,%o5,%o5
/* restore return address */ /* restore return address */
mov %o4,%o7 mov %o5,%o7
mov %o5,%o4
/* o4 has the GOT pointer */ /* o4 has the GOT pointer */
#endif #endif
sethi %hi(C_SYMBOL_NAME(____sig_table)),%o5 sethi %hi(C_SYMBOL_NAME(____sig_table)),%o5
or %o5,%lo(C_SYMBOL_NAME(____sig_table)),%o5 or %o5,%lo(C_SYMBOL_NAME(____sig_table)),%o5
#ifdef PIC #ifdef PIC
add %o5,%o4,%o4 ld [%o4+%o5], %o5
ld [%o4],%o5
#endif #endif
sll %o0,2,%o4 sll %o0,2,%o4
add %o5,%o4,%o4 add %o5,%o4,%o4
@ -141,3 +136,5 @@ ___syy:
/* if we return, sysreturn failed */ /* if we return, sysreturn failed */
mov SYS_ify(exit),%g1 mov SYS_ify(exit),%g1
t 0x10 t 0x10
END(____sparc_signal_trampoline)

View File

@ -0,0 +1,39 @@
/* Copyright (C) 1997 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 Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <unistd.h>
#include <sys/param.h>
/* Return the system page size. This value will either be 4k or 8k depending
on whether or not we are running on Sparc v9 machine. */
/* If we are not a static program, this value is collected from the system
via the AT_PAGESZ auxiliary argument. If we are a static program, we
have to guess. We should _really_ get Linux a proper sysconf()... */
extern size_t _dl_pagesize;
int
__getpagesize ()
{
if (_dl_pagesize == 0)
_dl_pagesize = EXEC_PAGESIZE;
return _dl_pagesize;
}
weak_alias (__getpagesize, getpagesize)

View File

@ -21,32 +21,76 @@
This is done in one of two ways: either in the stack context This is done in one of two ways: either in the stack context
of program start, or having dlopen pass them in. */ of program start, or having dlopen pass them in. */
#define SYSDEP_CALL_INIT(NAME, INIT) \ #include <sysdep.h>
void NAME (void *arg) \
{ \
int argc; \
char **argv, **envp; \
/* The next variable is only here to work around a bug in gcc <= 2.7.2.2. \
If the address would be taken inside the expression the optimizer \
would try to be too smart and throws it away. Grrr. */ \
int *dummy_addr = &_dl_starting_up; \
\
__libc_multiple_libcs = dummy_addr && !_dl_starting_up; \
\
if (!__libc_multiple_libcs) \
{ \
argc = *(int *) arg; \
argv = (char **) (arg + 4); \
envp = &argv[argc+1]; \
} \
else \
{ \
argc = (int) arg; \
argv = ((char ***) &arg)[1]; \
envp = ((char ***) &arg)[2]; \
} \
\
INIT (argc, argv, envp); \
}
#define __S1(x) #x
#define __S(x) __S1(x)
#ifdef PIC
#define SYSDEP_CALL_INIT(NAME, INIT) asm("\
.weak _dl_starting_up
.global " #NAME "
.type " #NAME ",@function
" #NAME ":
save %sp, -64, %sp
1: call 11f
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
11: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
add %l7, %o7, %l7
/* Are we a dynamic libc being loaded into a static program? */
sethi %hi(_dl_starting_up), %l2
or %l2, %lo(_dl_starting_up), %l2
ld [%l7+%l2], %l2
cmp %l2, 0
beq 3f
sethi %hi(__libc_multiple_libcs), %l3
ld [%l2], %l2
subcc %g0, %l2, %g0
subx %g0, -1, %l2
3: or %l3, %lo(__libc_multiple_libcs), %l3
ld [%l7+%l3], %l3
cmp %l2, 0
st %l2, [%l3]
/* If so, argc et al are in %o0-%o2 already. Otherwise, load them. */
bnz " #INIT "
restore
ld [%sp+22*4], %o0
add %sp, 23*4, %o1
sll %o0, 2, %o2
add %o2, %o1, %o2
ba " #INIT "
add %o2, 4, %o2
.size "#NAME ", .-" #NAME);
#else
#define SYSDEP_CALL_INIT(NAME, INIT) asm("\
.weak _dl_starting_up
.global " #NAME "
.type " #NAME ",@function
" #NAME ":
/* Are we a dynamic libc being loaded into a static program? */
sethi %hi(_dl_starting_up), %g2
or %g2, %lo(_dl_starting_up), %g2
cmp %g2, 0
beq 3f
sethi %hi(__libc_multiple_libcs), %g3
ld [%g4+%g2], %g2
subcc %g0, %g2, %g0
subx %g0, -1, %g2
3: or %g3, %lo(__libc_multiple_libcs), %g3
cmp %g2, 0
st %g2, [%g3+%g4]
/* If so, argc et al are in %o0-%o2 already. Otherwise, load them. */
bnz " #INIT "
nop
ld [%sp+22*4], %o0
add %sp, 23*4, %o1
sll %o0, 2, %o2
add %o2, %o1, %o2
ba " #INIT "
add %o2, 4, %o2
.size "#NAME ", .-" #NAME);
#endif

View File

@ -36,44 +36,51 @@
/* Linux/SPARC uses a different trap number */ /* Linux/SPARC uses a different trap number */
#undef PSEUDO #undef PSEUDO
#undef ENTRY #undef ENTRY
#undef END
#undef LOC
#define ENTRY(name) \ #define ENTRY(name) \
.global C_SYMBOL_NAME(name); \ .global C_SYMBOL_NAME(name); \
.align 2;\ .align 4;\
C_LABEL(name);\ C_LABEL(name);\
.type name,@function; .type name,@function;
#define END(name) \
.size name, . - name
#define LOC(name) . ## L ## name
#ifdef PIC #ifdef PIC
#define SYSCALL_ERROR_HANDLER \ #define SYSCALL_ERROR_HANDLER \
.global C_SYMBOL_NAME(__errno_location);\ .global C_SYMBOL_NAME(__errno_location); \
.type C_SYMBOL_NAME(__errno_location),@function;\ .type C_SYMBOL_NAME(__errno_location),@function; \
save %sp,-96,%sp;\ save %sp,-96,%sp; \
call __errno_location;\ call __errno_location; \
nop;\ nop; \
st %i0,[%o0];\ st %i0,[%o0]; \
restore;\ restore; \
retl;\ retl; \
mov -1,%o0; mov -1,%o0;
#else #else
#define SYSCALL_ERROR_HANDLER \ #define SYSCALL_ERROR_HANDLER \
save %sp,-96,%sp; \ save %sp,-96,%sp; \
call __errno_location; \ call __errno_location; \
nop; \ nop; \
st %i0,[%o0]; \ st %i0,[%o0]; \
restore; \ restore; \
retl; \ retl; \
mov -1,%o0; mov -1,%o0;
#endif /* PIC */ #endif /* PIC */
#define PSEUDO(name, syscall_name, args) \ #define PSEUDO(name, syscall_name, args) \
.text; \ .text; \
ENTRY(name); \ ENTRY(name); \
LOADSYSCALL(syscall_name); \ LOADSYSCALL(syscall_name); \
ta 0x10; \ ta 0x10; \
bcc,a 1f; \ bcc,a 9000f; \
nop; \ nop; \
SYSCALL_ERROR_HANDLER; \ SYSCALL_ERROR_HANDLER; \
1:; 9000:;
#endif /* ASSEMBLER */ #endif /* ASSEMBLER */

View File

@ -42,7 +42,7 @@ typedef signed long int __int64_t;
typedef unsigned long int __uint64_t; typedef unsigned long int __uint64_t;
typedef __quad_t *__qaddr_t; typedef __quad_t *__qaddr_t;
typedef __u_int __dev_t; /* Type of device numbers. */ typedef __u_long __dev_t; /* Type of device numbers. */
typedef __u_int __uid_t; /* Type of user identifications. */ typedef __u_int __uid_t; /* Type of user identifications. */
typedef __u_int __gid_t; /* Type of group identifications. */ typedef __u_int __gid_t; /* Type of group identifications. */
typedef __u_int __ino_t; /* Type of file serial numbers. */ typedef __u_int __ino_t; /* Type of file serial numbers. */

View File

@ -55,7 +55,7 @@
restore restore
ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0 ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0
add %sp, " __S(STACK_BIAS) "+23*8, %o1 add %sp, " __S(STACK_BIAS) "+23*8, %o1
sll %o0, 3, %o2 sllx %o0, 3, %o2
add %o2, %o1, %o2 add %o2, %o1, %o2
ba " #INIT " ba " #INIT "
add %o2, 8, %o2 add %o2, 8, %o2
@ -83,10 +83,10 @@
nop nop
ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0 ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0
add %sp, " __S(STACK_BIAS) "+23*8, %o1 add %sp, " __S(STACK_BIAS) "+23*8, %o1
sll %o0, 3, %o2 sllx %o0, 3, %o2
add %o2, %o1, %o2 add %o2, %o1, %o2
add %o2, 8, %o2 ba " #INIT "
ba,a " #INIT " add %o2, 8, %o2
.size "#NAME ", .-" #NAME); .size "#NAME ", .-" #NAME);
#endif #endif