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>
* 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_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_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>

49
FAQ
View File

@ -565,7 +565,7 @@ by
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.
@ -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?''
[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
the type `size_t' is used for all parameters which describe a size.
So better change now.
This change is critical for system which have
sizeof (int) != sizeof (size_t)
like the Alpha.
follows the Single Unix specifications (and I think the POSIX.1g
draft which adopted the solution). The type for parameter describing
a size is now `socklen_t', a new type.
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@ -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
glibc 2.x?
[A20] {AJ} There's only support for glibc 2.0 in gcc 2.7.2.2 or later.
gcc 2.7.2.2 has also a nasty bug. It installs its own version of
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
-----------------------------------------------------------------------
[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
had problems with glibc support.
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@ -699,12 +676,12 @@ very beginning and if it is not usable `configure' will bark.
works great. But the glibc NIS+ doesn't seem to work.''
[A24] The glibc NIS+ implementation uses a /var/nis/NIS_COLD_START
file for storing information about the NIS+ server and their
public keys, because the nis.conf file do not contain all
necessary information. You have to copy a NIS_COLD_START file
from a Solaris client (the NIS_COLD_START file is byte order
independend) or generate it new with nisinit from the nis-tools
(look at http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html).
file for storing information about the NIS+ server and their public
keys, because the nis.conf file do not contain all necessary
information. You have to copy a NIS_COLD_START file from a Solaris
client (the NIS_COLD_START file is byte order independend) or generate
it new with nisinit from the nis-tools (look at
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 \
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
| mipstx39 | mipstx39el \
| sparc | sparclet | sparclite | sparc64)
basic_machine=$basic_machine-unknown
;;
@ -179,7 +180,9 @@ case $basic_machine in
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* | f301-*)
| mips64el-* | mips64orion-* | mips64orionel-* \
| mipstx39-* | mipstx39el-* \
| f301-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@ -568,6 +571,12 @@ case $basic_machine in
basic_machine=i386-sequent
os=-dynix
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
tower | tower-32)
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
# The makefiles need to use a different form to find it in $srcdir.
INSTALL='$(..)./install-sh -c'
INSTALL='\$(..)./install-sh -c'
fi
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
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
if test "$INSTALL" = "${srcdir}/install-sh -c"; then
# The makefiles need to use a different form to find it in $srcdir.
INSTALL='$(..)./install-sh -c'
INSTALL='\$(..)./install-sh -c'
fi
AC_PROG_LN_S
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
$(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
$(compile.c) -g0 -S -fPIC -finhibit-size-directive \
$(compile.c) -O0 -g0 -S -fPIC -finhibit-size-directive \
$(no-exceptions) -o $@
# 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. */
#define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
+ 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
@ -138,7 +142,7 @@ _dl_map_object_deps (struct link_map *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
+ l->l_info[DT_STRTAB]->d_un.d_ptr);
@ -190,27 +194,41 @@ _dl_map_object_deps (struct link_map *map,
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;
const char *objname;
struct list *newp;
if (d->d_tag == DT_AUXILIARY)
{
/* Store the tag in the argument structure. */
args.d = d;
/* 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
{
/* 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. */
struct list *newp = alloca (sizeof (struct list));
newp = alloca (sizeof (struct list));
/* Copy the content of the current entry over. */
memcpy (newp, orig, sizeof (*newp));
@ -232,14 +250,14 @@ _dl_map_object_deps (struct link_map *map,
*/
if (args.aux->l_reserved)
{
/* The object is already somewhere in the
list. Locate it first. */
/* The object is already somewhere in the list.
Locate it first. */
struct list *late;
/* 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. */
/* 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)
@ -253,8 +271,7 @@ _dl_map_object_deps (struct link_map *map,
move it to this earlier position. */
orig->unique = newp;
/* Now remove the later entry from the unique
list. */
/* Now remove the later entry from the unique list. */
late->unique = late->unique->unique;
/* We must move the earlier in the chain. */
@ -271,18 +288,18 @@ _dl_map_object_deps (struct link_map *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. */
/* 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. */
/* 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;
@ -291,18 +308,15 @@ _dl_map_object_deps (struct link_map *map,
}
else
{
/* This is easy. We just add the symbol right
here. */
/* 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. */
/* 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. */
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)
@ -328,7 +342,6 @@ _dl_map_object_deps (struct link_map *map,
++nduplist;
}
}
}
else
/* Mark as processed. */
runp->done = 1;

View File

@ -406,6 +406,9 @@ _dl_init_paths (void)
{
fake_path_list = (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, ":;",
__libc_enable_secure ? trusted_dirs : NULL);
@ -901,20 +904,30 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
/* Look for this name among those already loaded. */
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,
use that object. */
(l->l_info[DT_SONAME] &&
! strcmp (name, (const char *) (l->l_addr +
l->l_info[DT_STRTAB]->d_un.d_ptr +
l->l_info[DT_SONAME]->d_un.d_val))))
{
/* The object is already loaded.
Just bump its reference count and return it. */
const char *soname = (const char *) (l->l_addr +
l->l_info[DT_STRTAB]->d_un.d_ptr +
l->l_info[DT_SONAME]->d_un.d_val);
/* If the requested name matches the soname of a loaded object,
use that object. Elide this check for names that have not
yet been opened. */
if (l->l_opencount <= 0)
continue;
if (!_dl_name_match_p (name, l))
{
const char *soname;
if (l->l_info[DT_SONAME] == NULL)
continue;
soname = (const char *) (l->l_addr
+ l->l_info[DT_STRTAB]->d_un.d_ptr
+ 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;
}

View File

@ -93,6 +93,10 @@ do_lookup (const char *undef_name, unsigned long int hash,
map->l_type == lt_executable)
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);
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)
@ -364,8 +368,13 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
void
_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;
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++;
nchain = *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))
#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
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. */
@ -120,6 +124,7 @@ fixup (
const PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
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. */
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)],
&l->l_versions[ndx],
(void *) (l->l_addr + reloc->r_offset));
(void *) rel_addr);
}
else
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;
/* Return the address that was written by the relocation. */
#ifdef ELF_FIXUP_RETURNS_ADDRESS
return (ElfW(Addr))(l->l_addr + reloc->r_offset);
#else
return *(ElfW(Addr) *) (l->l_addr + reloc->r_offset);
#endif
return ELF_FIXUP_RETURN_VALUE(l, *rel_addr);
}
@ -219,17 +220,10 @@ profile_fixup (
}
*_dl_global_scope_end = NULL;
(*mcount_fct) (retaddr, result);
/* Return the address that was written by the relocation. */
#ifdef ELF_FIXUP_RETURNS_ADDRESS
(*mcount_fct) (retaddr, result);
return &result; /* XXX This cannot work. What to do??? --drepper */
#else
(*mcount_fct) (retaddr, result);
return result;
#endif
return ELF_FIXUP_RETURN_VALUE(l, result);
}
#endif

View File

@ -155,16 +155,23 @@ int
_dl_check_map_versions (struct link_map *map, int verbose)
{
int result = 0;
const char *strtab = (const char *) (map->l_addr
+ map->l_info[DT_STRTAB]->d_un.d_ptr);
const char *strtab;
/* Pointer to section with needed versions. */
ElfW(Dyn) *dyn = map->l_info[VERSTAG (DT_VERNEED)];
ElfW(Dyn) *dyn;
/* 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
in a dependecy. */
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)
{
/* 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_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. */
/* 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,
const char *errsting);
int _dl_argc;
char **_dl_argv;
const char *_dl_rpath;
int _dl_verbose;
const char *_dl_platform;
size_t _dl_platformlen;
unsigned long _dl_hwcap;
struct r_search_path *_dl_search_paths;
const char *_dl_profile;
const char *_dl_profile_output;
@ -80,6 +80,7 @@ static void dl_main (const ElfW(Phdr) *phdr,
struct link_map _dl_rtld_map;
struct libname_list _dl_rtld_libname;
struct libname_list _dl_rtld_libname2;
#ifdef RTLD_START
RTLD_START
@ -119,19 +120,22 @@ _dl_start (void *arg)
the operating system's program loader where to find the program
header table in core. */
/* Transfer data about ourselves to the permanent link_map structure. */
_dl_rtld_map.l_addr = bootstrap_map.l_addr;
_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,
sizeof _dl_rtld_map.l_info);
_dl_setup_hash (&_dl_rtld_map);
/* Cache the DT_RPATH stored in ld.so itself; this will be
the default search path. */
if (_dl_rtld_map.l_info[DT_STRTAB] && _dl_rtld_map.l_info[DT_RPATH])
{
_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
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.next = NULL;
_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;
break;
}
@ -696,27 +717,26 @@ 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)
{
const char *strtab =
(const char *) (map->l_addr
+ map->l_info[DT_STRTAB]->d_un.d_ptr);
const char *strtab;
ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
ElfW(Verneed) *ent;
if (dyn != NULL)
{
ElfW(Verneed) *ent =
(ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
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)
{
_dl_sysdep_message ("\n\tVersion information:\n",
NULL);
_dl_sysdep_message ("\n\tVersion information:\n", NULL);
first = 0;
}
_dl_sysdep_message ("\t", (map->l_name[0]
? map->l_name
: _dl_argv[0]), ":\n",
NULL);
? map->l_name : _dl_argv[0]),
":\n", NULL);
while (1)
{
@ -740,8 +760,7 @@ of this helper program; chances are you did not intend to run this program.\n",
"=> ", NULL);
if (needed != NULL
&& match_version (strtab + aux->vna_name,
needed))
&& match_version (strtab+aux->vna_name, needed))
fname = needed->l_name;
_dl_sysdep_message (fname ?: "not found", "\n",
@ -761,9 +780,7 @@ of this helper program; chances are you did not intend to run this program.\n",
break;
/* Next dependency. */
ent = (ElfW(Verneed) *) ((char *) ent
+ ent->vn_next);
}
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]]
Beside the first all of them are allowed to be missing. If the
full specified locale is not found, the less specific one are
looked for. The various part will be stripped of according to
Beside the first part all of them are allowed to be missing. If
the full specified locale is not found, the less specific one are
looked for. The various parts will be stripped off according to
the following order:
(1) revision
(2) sponsor

View File

@ -85,7 +85,7 @@ void free ();
# define strdup __strdup
/* 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);
#endif

View File

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

View File

@ -51,6 +51,12 @@ typedef struct _IO_FILE FILE;
#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'. */
typedef _G_fpos_t fpos_t;
@ -235,36 +241,40 @@ extern int vsprintf __P ((char *__restrict __s,
_G_va_list __arg));
#ifdef __OPTIMIZE__
extern __inline int
__STDIO_INLINE int
vprintf (const char *__restrict __fmt, _G_va_list __arg)
{
return vfprintf (stdout, __fmt, __arg);
}
#endif /* Optimizing. */
#if defined __USE_GNU || defined __USE_ISOC9X
#if defined __USE_BSD || defined __USE_ISOC9X
/* Maximum chars of output to write in MAXLEN. */
extern int __snprintf __P ((char *__s, size_t __maxlen,
__const char *__format, ...));
extern int snprintf __P ((char *__s, size_t __maxlen,
__const char *__format, ...));
extern int __snprintf __P ((char *__restrict __s, size_t __maxlen,
__const char *__restrict __format, ...));
extern int snprintf __P ((char *__restrict __s, size_t __maxlen,
__const char *__restrict __format, ...));
extern int __vsnprintf __P ((char *__s, size_t __maxlen,
__const char *__format, _G_va_list __arg));
extern int vsnprintf __P ((char *__s, size_t __maxlen,
__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));
extern int vsnprintf __P ((char *__restrict __s, size_t __maxlen,
__const char *__restrict __format,
_G_va_list __arg));
#endif
#ifdef __USE_GNU
/* Write formatted output to a string dynamically allocated with `malloc'.
Store the address of the string in *PTR. */
extern int vasprintf __P ((char **__ptr, __const char *__f,
_G_va_list __arg));
extern int asprintf __P ((char **__ptr, __const char *__fmt, ...));
extern int vasprintf __P ((char **__restrict __ptr,
__const char *__restrict __f, _G_va_list __arg));
extern int asprintf __P ((char **__restrict __ptr,
__const char *__restrict __fmt, ...));
/* Write formatted output to a file descriptor. */
extern int vdprintf __P ((int __fd, __const char *__fmt, _G_va_list __arg));
extern int dprintf __P ((int __fd, __const char *__fmt, ...));
extern int vdprintf __P ((int __fd, __const char *__restrict __fmt,
_G_va_list __arg));
extern int dprintf __P ((int __fd, __const char *__restrict __fmt, ...));
#endif
@ -279,19 +289,24 @@ extern int sscanf __P ((__const char *__restrict __s,
#ifdef __USE_GNU
/* 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));
extern int vfscanf __P ((FILE *__s, __const char *__format,
extern int vfscanf __P ((FILE *__restrict __s,
__const char *__restrict __format,
_G_va_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 *__format, _G_va_list __arg));
extern int __vscanf __P ((__const char *__restrict __format,
_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. */
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));
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));
#endif /* Use GNU. */
@ -308,7 +323,7 @@ extern int getchar __P ((void));
#define getc(_fp) _IO_getc (_fp)
#ifdef __OPTIMIZE__
extern __inline int
__STDIO_INLINE int
getchar (void)
{
return _IO_getc (stdin);
@ -321,13 +336,13 @@ extern int getc_unlocked __P ((FILE *__stream));
extern int getchar_unlocked __P ((void));
#ifdef __OPTIMIZE__
extern __inline int
__STDIO_INLINE int
getc_unlocked (FILE *__fp)
{
return _IO_getc_unlocked (__fp);
}
extern __inline int
__STDIO_INLINE int
getchar_unlocked (void)
{
return _IO_getc_unlocked (stdin);
@ -348,7 +363,7 @@ extern int putchar __P ((int __c));
#define putc(_ch, _fp) _IO_putc (_ch, _fp)
#ifdef __OPTIMIZE__
extern __inline int
__STDIO_INLINE int
putchar (int __c)
{
return _IO_putc (__c, stdout);
@ -360,7 +375,7 @@ putchar (int __c)
extern int fputc_unlocked __P ((int __c, FILE *__stream));
#ifdef __OPTIMIZE__
extern __inline int
__STDIO_INLINE int
fputc_unlocked (int __c, FILE *__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));
#ifdef __OPTIMIZE__
extern __inline int
__STDIO_INLINE int
putc_unlocked (int __c, FILE *__stream)
{
return _IO_putc_unlocked (__c, __stream);
}
extern __inline int
__STDIO_INLINE int
putchar_unlocked (int __c)
{
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));
#ifdef __OPTIMIZE__
extern __inline _IO_ssize_t
__STDIO_INLINE _IO_ssize_t
getline (char **__lineptr, size_t *__n, FILE *__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));
#ifdef __OPTIMIZE__
extern __inline int
__STDIO_INLINE int
feof_unlocked (FILE *__stream)
{
return _IO_feof_unlocked (__stream);
}
extern __inline int
__STDIO_INLINE int
ferror_unlocked (FILE *__stream)
{
return _IO_ferror_unlocked (__stream);
@ -579,6 +594,9 @@ extern void funlockfile __P ((FILE *__stream));
__END_DECLS
/* Define helper macro. */
#undef __STDIO_INLINE
#endif /* <stdio.h> included. */
#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).
*
* If you find something missing or wrong contact <bug-glibc@prep.ai.mit.edu>
*
* !!! The list has to be sorted !!!
*/
DEFINE_INT_CURR("AED ") /* United Arab Emirates */
DEFINE_INT_CURR("AFA ") /* Afghanistan */
DEFINE_INT_CURR("ALL ") /* Albania */
DEFINE_INT_CURR("ADP ") /* Andorran Peseta */
DEFINE_INT_CURR("AED ") /* United Arab Emirates Dirham */
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("AOK ") /* Angola */
DEFINE_INT_CURR("ARP ") /* Argentina */
DEFINE_INT_CURR("ATS ") /* Austria */
DEFINE_INT_CURR("AUD ") /* Australia */
DEFINE_INT_CURR("BBD ") /* Barbados */
DEFINE_INT_CURR("BDT ") /* Bangladesh */
DEFINE_INT_CURR("BEF ") /* Belgium */
DEFINE_INT_CURR("BGL ") /* Bulgaria */
DEFINE_INT_CURR("BHD ") /* Bahrain */
DEFINE_INT_CURR("AOK ") /* Angolan Kwanza */
DEFINE_INT_CURR("AON ") /* Angolan New Kwanza */
DEFINE_INT_CURR("ARP ") /* Argentine Peso */
DEFINE_INT_CURR("ATS ") /* Austrian Schilling */
DEFINE_INT_CURR("AUD ") /* Australian Dollar */
DEFINE_INT_CURR("AZM ") /* Azerbaijan Manat */
DEFINE_INT_CURR("BBD ") /* Barbados Dollar */
DEFINE_INT_CURR("BDT ") /* Bangladesh Taka */
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("BMD ") /* Burmuda */
DEFINE_INT_CURR("BND ") /* Brunei */
DEFINE_INT_CURR("BOP ") /* Bolivia */
DEFINE_INT_CURR("BRC ") /* Brazil */
DEFINE_INT_CURR("BSD ") /* Bahamas */
DEFINE_INT_CURR("BMD ") /* Burmudian Dollar */
DEFINE_INT_CURR("BND ") /* Brunei Dollar */
DEFINE_INT_CURR("BOP ") /* Bolivian Boliviano */
DEFINE_INT_CURR("BPS ") /* Canton and Enderbury Islands */
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("BWP ") /* Botswana */
DEFINE_INT_CURR("BZD ") /* Belize */
DEFINE_INT_CURR("CAD ") /* Canada */
DEFINE_INT_CURR("CHF ") /* Switzerland, Liechtenstein */
DEFINE_INT_CURR("CLP ") /* Chile */
DEFINE_INT_CURR("CNY ") /* China */
DEFINE_INT_CURR("COP ") /* Colombia */
DEFINE_INT_CURR("CRC ") /* Costa Rica */
DEFINE_INT_CURR("CSK ") /* Czechoslovakia */
DEFINE_INT_CURR("CUP ") /* Cuba */
DEFINE_INT_CURR("CVE ") /* Cape Verde */
DEFINE_INT_CURR("CYP ") /* Cyprus */
DEFINE_INT_CURR("DEM ") /* Germany */
DEFINE_INT_CURR("DJF ") /* Djibouti */
DEFINE_INT_CURR("DKK ") /* Denmark */
DEFINE_INT_CURR("BWP ") /* Botswana Pula */
DEFINE_INT_CURR("BZD ") /* Belize Dollar */
DEFINE_INT_CURR("CAD ") /* Canadian Dollar */
DEFINE_INT_CURR("CFP ") /* French Pacific Island Franc */
DEFINE_INT_CURR("CHF ") /* Swiss Franc (Liechtenstein) */
DEFINE_INT_CURR("CLP ") /* Chilean Peso */
DEFINE_INT_CURR("CNY ") /* China Yuan Renminbi */
DEFINE_INT_CURR("COP ") /* Colombian Peso */
DEFINE_INT_CURR("CRC ") /* Costa Rican Colon */
DEFINE_INT_CURR("CUP ") /* Cuban Peso */
DEFINE_INT_CURR("CVE ") /* Cape Verde Escudo */
DEFINE_INT_CURR("CYP ") /* Cypriot Pound */
DEFINE_INT_CURR("CZK ") /* Czech Koruna */
DEFINE_INT_CURR("DEM ") /* German Mark */
DEFINE_INT_CURR("DJF ") /* Djibouti Franc */
DEFINE_INT_CURR("DKK ") /* Danish Krone (Faroe Islands, Greenland) */
DEFINE_INT_CURR("DOP ") /* Dominican Republic */
DEFINE_INT_CURR("DZD ") /* Algeria */
DEFINE_INT_CURR("ECS ") /* Ecuador */
DEFINE_INT_CURR("EEK ") /* Estonia */
DEFINE_INT_CURR("EGP ") /* Egypt */
DEFINE_INT_CURR("ESP ") /* Spain */
DEFINE_INT_CURR("ETB ") /* Ethiopia */
DEFINE_INT_CURR("FIM ") /* Finland */
DEFINE_INT_CURR("FJD ") /* Fiji */
DEFINE_INT_CURR("FKP ") /* Falkland Islands (Malvinas) */
DEFINE_INT_CURR("FRF ") /* France */
DEFINE_INT_CURR("GBP ") /* Great Britain */
DEFINE_INT_CURR("GHC ") /* Ghana */
DEFINE_INT_CURR("GIP ") /* Gibraltar */
DEFINE_INT_CURR("GMD ") /* Gambia */
DEFINE_INT_CURR("GNS ") /* Guinea */
DEFINE_INT_CURR("GQE ") /* Equatorial Guinea */
DEFINE_INT_CURR("GRD ") /* Greece */
DEFINE_INT_CURR("GTQ ") /* Guatemala */
DEFINE_INT_CURR("GWP ") /* Guinea-Bissau */
DEFINE_INT_CURR("GYD ") /* Guyana */
DEFINE_INT_CURR("HKD ") /* Hong Kong */
DEFINE_INT_CURR("HNL ") /* Honduras */
DEFINE_INT_CURR("HRD ") /* Croatia */
DEFINE_INT_CURR("HTG ") /* Haiti */
DEFINE_INT_CURR("HUF ") /* Hungary */
DEFINE_INT_CURR("IDR ") /* Indonesia */
DEFINE_INT_CURR("IEP ") /* Ireland */
DEFINE_INT_CURR("ILS ") /* Israel */
DEFINE_INT_CURR("INR ") /* India, Bhutan */
DEFINE_INT_CURR("IQD ") /* Iraq */
DEFINE_INT_CURR("IRR ") /* Iran */
DEFINE_INT_CURR("ISK ") /* Iceland */
DEFINE_INT_CURR("ITL ") /* Italy */
DEFINE_INT_CURR("JMD ") /* Jamaica */
DEFINE_INT_CURR("JOD ") /* Jordan */
DEFINE_INT_CURR("JPY ") /* Japan */
DEFINE_INT_CURR("KES ") /* Kenya */
DEFINE_INT_CURR("KHR ") /* Democratic Kampuchea */
DEFINE_INT_CURR("KMF ") /* Comoros */
DEFINE_INT_CURR("KPW ") /* Democratic People's of Korea */
DEFINE_INT_CURR("KRW ") /* Republic of Korea */
DEFINE_INT_CURR("KWD ") /* Kuwait */
DEFINE_INT_CURR("DZD ") /* Algerian Dinar */
DEFINE_INT_CURR("ECS ") /* Ecuadoran Sucre */
DEFINE_INT_CURR("EEK ") /* Estonian Kroon */
DEFINE_INT_CURR("EGP ") /* Egyptian Pound */
DEFINE_INT_CURR("ESP ") /* Spanish Peseta */
DEFINE_INT_CURR("ETB ") /* Ethiopian Birr */
DEFINE_INT_CURR("EUR ") /* European Union Euro */
DEFINE_INT_CURR("FIM ") /* Finnish Markka */
DEFINE_INT_CURR("FJD ") /* Fiji Dollar */
DEFINE_INT_CURR("FKP ") /* Falkland Islands Pound (Malvinas) */
DEFINE_INT_CURR("FRF ") /* French Franc */
DEFINE_INT_CURR("GBP ") /* British Pound */
DEFINE_INT_CURR("GEK ") /* Georgia Lari */
DEFINE_INT_CURR("GHC ") /* Ghana Cedi */
DEFINE_INT_CURR("GIP ") /* Gibraltar Pound */
DEFINE_INT_CURR("GMD ") /* Gambian Dalasi */
DEFINE_INT_CURR("GNS ") /* Guinea Syli */
DEFINE_INT_CURR("GQE ") /* Equatorial Guinea Ekwele */
DEFINE_INT_CURR("GRD ") /* Greek Drachma */
DEFINE_INT_CURR("GTQ ") /* Guatemala Quetzal */
DEFINE_INT_CURR("GWP ") /* Guinea-Bissau Peso */
DEFINE_INT_CURR("GYD ") /* Guyana Dollar */
DEFINE_INT_CURR("HKD ") /* Hong Kong Dollar */
DEFINE_INT_CURR("HNL ") /* Honduras Lempira */
DEFINE_INT_CURR("HRK ") /* Croatia Kuna */
DEFINE_INT_CURR("HTG ") /* Haiti Gourde */
DEFINE_INT_CURR("HUF ") /* Hungarian Forint */
DEFINE_INT_CURR("IDR ") /* Indonesia Rupiah */
DEFINE_INT_CURR("IEP ") /* Irish Pound */
DEFINE_INT_CURR("ILS ") /* Israeli Shekel */
DEFINE_INT_CURR("INR ") /* Indian Rupee (Bhutan) */
DEFINE_INT_CURR("IQD ") /* Iraqi Dinar */
DEFINE_INT_CURR("IRR ") /* Iranian Rial */
DEFINE_INT_CURR("ISK ") /* Iceland Krona */
DEFINE_INT_CURR("ITL ") /* Italian Lira (San Marino, Vatican City) */
DEFINE_INT_CURR("JMD ") /* Jamaican Dollar */
DEFINE_INT_CURR("JOD ") /* Jordanian Dinar */
DEFINE_INT_CURR("JPY ") /* Japanese Yen */
DEFINE_INT_CURR("KES ") /* Kenyan Shilling */
DEFINE_INT_CURR("KGS ") /* Kyrgyzstan Som */
DEFINE_INT_CURR("KHR ") /* Democratic Kampuchea Riel */
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("LAK ") /* Lao People's Democratic Republic */
DEFINE_INT_CURR("LBP ") /* Lebanon */
DEFINE_INT_CURR("LKR ") /* Sri Lanka */
DEFINE_INT_CURR("LRD ") /* Liberia */
DEFINE_INT_CURR("LSM ") /* Lesotho */
DEFINE_INT_CURR("LTL ") /* Lithuania */
DEFINE_INT_CURR("LUF ") /* Luxembourg */
DEFINE_INT_CURR("LVL ") /* Latvia */
DEFINE_INT_CURR("LYD ") /* Libyan Arab Jamahiriya */
DEFINE_INT_CURR("MAD ") /* Morocco */
DEFINE_INT_CURR("MGF ") /* Madagascar */
DEFINE_INT_CURR("MLF ") /* Mali */
DEFINE_INT_CURR("MNT ") /* Mongolia */
DEFINE_INT_CURR("MOP ") /* Macau */
DEFINE_INT_CURR("MRO ") /* Mauritania */
DEFINE_INT_CURR("MTP ") /* Malta */
DEFINE_INT_CURR("MUR ") /* Mauritius */
DEFINE_INT_CURR("MVR ") /* Maldives */
DEFINE_INT_CURR("MWK ") /* Malawi */
DEFINE_INT_CURR("MXP ") /* Mexico */
DEFINE_INT_CURR("MYR ") /* Malaysia */
DEFINE_INT_CURR("MZM ") /* Mozambique */
DEFINE_INT_CURR("NGN ") /* Nigeria */
DEFINE_INT_CURR("NIC ") /* Nicaragua */
DEFINE_INT_CURR("NLG ") /* Netherlands */
DEFINE_INT_CURR("NOK ") /* Norway */
DEFINE_INT_CURR("NPR ") /* Nepal */
DEFINE_INT_CURR("NZD ") /* New Zealand */
DEFINE_INT_CURR("OMR ") /* Oman */
DEFINE_INT_CURR("PAB ") /* Panama */
DEFINE_INT_CURR("PES ") /* Peru */
DEFINE_INT_CURR("PGK ") /* Papau New Guinea */
DEFINE_INT_CURR("PHP ") /* Philippines */
DEFINE_INT_CURR("PKR ") /* Pakistan */
DEFINE_INT_CURR("PLZ ") /* Poland */
DEFINE_INT_CURR("PTE ") /* Portugal */
DEFINE_INT_CURR("PYG ") /* Paraguay */
DEFINE_INT_CURR("QAR ") /* Qatar */
DEFINE_INT_CURR("ROL ") /* Romania */
DEFINE_INT_CURR("RUR ") /* Russia */
DEFINE_INT_CURR("RWF ") /* Rwanda */
DEFINE_INT_CURR("SAR ") /* Saudi Arabia */
DEFINE_INT_CURR("SBD ") /* Solomon Islands */
DEFINE_INT_CURR("SCR ") /* Seychelles */
DEFINE_INT_CURR("SDP ") /* Sudan */
DEFINE_INT_CURR("SEK ") /* Sweden */
DEFINE_INT_CURR("SGD ") /* Singapore */
DEFINE_INT_CURR("SHP ") /* St. Helena */
DEFINE_INT_CURR("SIT ") /* Slovenia */
DEFINE_INT_CURR("SLL ") /* Sierra Leone */
DEFINE_INT_CURR("SOS ") /* Somalia */
DEFINE_INT_CURR("SRG ") /* Suriname */
DEFINE_INT_CURR("STD ") /* Sao Tome and Principe */
DEFINE_INT_CURR("SUR ") /* Ukrainian, Byelorussion */
DEFINE_INT_CURR("SVC ") /* El Salvador */
DEFINE_INT_CURR("SYP ") /* Syrian Arab Republic */
DEFINE_INT_CURR("SZL ") /* Swaziland */
DEFINE_INT_CURR("THB ") /* Thailand */
DEFINE_INT_CURR("TND ") /* Tunisia */
DEFINE_INT_CURR("TOP ") /* Tonga */
DEFINE_INT_CURR("TPE ") /* East Timor */
DEFINE_INT_CURR("TRL ") /* Turkey */
DEFINE_INT_CURR("KZT ") /* Kazakhstan Tenge */
DEFINE_INT_CURR("LAK ") /* Lao People's Democratic Republic New Kip */
DEFINE_INT_CURR("LBP ") /* Lebanese Pound */
DEFINE_INT_CURR("LKR ") /* Sri Lankan Rupee */
DEFINE_INT_CURR("LRD ") /* Liberian Dollar */
DEFINE_INT_CURR("LSM ") /* Lesotho Maloti */
DEFINE_INT_CURR("LTL ") /* Lithuanian Litas */
DEFINE_INT_CURR("LUF ") /* Luxembourg Franc */
DEFINE_INT_CURR("LVL ") /* Latvia Lat */
DEFINE_INT_CURR("LYD ") /* Libyan Arab Jamahiriya Dinar */
DEFINE_INT_CURR("MAD ") /* Moroccan Dirham */
DEFINE_INT_CURR("MDL ") /* Moldova Lei */
DEFINE_INT_CURR("MGF ") /* Madagasy Franc */
DEFINE_INT_CURR("MLF ") /* Mali Franc */
DEFINE_INT_CURR("MMK ") /* Myanmar Kyat */
DEFINE_INT_CURR("MNT ") /* Mongolia Tugrik */
DEFINE_INT_CURR("MOP ") /* Macau Pataca */
DEFINE_INT_CURR("MRO ") /* Mauritania Ouguiya */
DEFINE_INT_CURR("MTP ") /* Maltese Lira */
DEFINE_INT_CURR("MUR ") /* Mauritius Rupee */
DEFINE_INT_CURR("MVR ") /* Maldives Rupee */
DEFINE_INT_CURR("MWK ") /* Malawi Kwacha */
DEFINE_INT_CURR("MXP ") /* Mexican Peso */
DEFINE_INT_CURR("MYR ") /* Malaysian Ringgit */
DEFINE_INT_CURR("MZM ") /* Mozambique Metical */
DEFINE_INT_CURR("NGN ") /* Nigeria Naira */
DEFINE_INT_CURR("NIC ") /* Nicaragua Cordoba */
DEFINE_INT_CURR("NLG ") /* Netherlands Guilder */
DEFINE_INT_CURR("NOK ") /* Norwegian Krone */
DEFINE_INT_CURR("NPR ") /* Nepalese Rupee */
DEFINE_INT_CURR("NZD ") /* New Zealand Dollar */
DEFINE_INT_CURR("OMR ") /* Omani Rial */
DEFINE_INT_CURR("PAB ") /* Panamaniam Balboa */
DEFINE_INT_CURR("PEN ") /* Peruvian New Sol */
DEFINE_INT_CURR("PGK ") /* Papau New Guinea Kina */
DEFINE_INT_CURR("PHP ") /* Philippines Peso */
DEFINE_INT_CURR("PKR ") /* Pakistan Rupee */
DEFINE_INT_CURR("PLZ ") /* Polish Zloty */
DEFINE_INT_CURR("PTE ") /* Portugese Escudo */
DEFINE_INT_CURR("PYG ") /* Paraguay Guarani */
DEFINE_INT_CURR("QAR ") /* Qatar Rial */
DEFINE_INT_CURR("ROL ") /* Romanian Leu */
DEFINE_INT_CURR("RUR ") /* Russian Ruble */
DEFINE_INT_CURR("RWF ") /* Rwanda Franc */
DEFINE_INT_CURR("SAR ") /* Saudi Arabia Riyal */
DEFINE_INT_CURR("SBD ") /* Solomon Islands Dollar */
DEFINE_INT_CURR("SCR ") /* Seychelles Rupee */
DEFINE_INT_CURR("SDP ") /* Sudanese Pound */
DEFINE_INT_CURR("SEK ") /* Swedish Krona */
DEFINE_INT_CURR("SGD ") /* Singapore Dollar */
DEFINE_INT_CURR("SHP ") /* St. Helena Pound */
DEFINE_INT_CURR("SIT ") /* Slovenian Tolar */
DEFINE_INT_CURR("SKK ") /* Slovakian Koruna */
DEFINE_INT_CURR("SLL ") /* Sierra Leone Leone */
DEFINE_INT_CURR("SOS ") /* Somalia Schilling */
DEFINE_INT_CURR("SRG ") /* Suriname Guilder */
DEFINE_INT_CURR("STD ") /* Sao Tome and Principe Dobra */
DEFINE_INT_CURR("SUR ") /* Soviet Union Rubel (Ukrainian, Byelorussion) */
DEFINE_INT_CURR("SVC ") /* El Salvador Colon */
DEFINE_INT_CURR("SYP ") /* Syrian Arab Republic Pound */
DEFINE_INT_CURR("SZL ") /* Swaziland Lilangeni */
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("TWD ") /* Taiwan, Province of China */
DEFINE_INT_CURR("TZS ") /* United Republic of Tanzania */
DEFINE_INT_CURR("UGS ") /* Uganda */
DEFINE_INT_CURR("USD ") /* United States */
DEFINE_INT_CURR("UYP ") /* Uruguay */
DEFINE_INT_CURR("VEB ") /* Venezuela */
DEFINE_INT_CURR("VND ") /* Viet Nam */
DEFINE_INT_CURR("VUV ") /* Vanuatu */
DEFINE_INT_CURR("WST ") /* Samoa */
DEFINE_INT_CURR("XAF ") /* United Republic of Cameroon, Central African Republic, Chad, Congo, Gabon */
DEFINE_INT_CURR("XCD ") /* Antiqua, Dominica, Grenada, Montserrat, St. Kitts-Nevis-Anguilla, Saint Lucia, Saint Vincent and the Grenadines */
DEFINE_INT_CURR("XOF ") /* Benin, Ivory Coast, Niger, Senegal, Togo, Upper Volta */
DEFINE_INT_CURR("TWD ") /* Taiwan, Province of China Dollar */
DEFINE_INT_CURR("TZS ") /* United Republic of Tanzania Shilling */
DEFINE_INT_CURR("UAK ") /* Ukraine Hryvna */
DEFINE_INT_CURR("UGS ") /* Ugandan Shilling */
DEFINE_INT_CURR("USD ") /* United States Dollar */
DEFINE_INT_CURR("UYP ") /* Uruguay Peso */
DEFINE_INT_CURR("UYU ") /* Uruguay New Peso */
DEFINE_INT_CURR("UZS ") /* Uzbekistan Sum */
DEFINE_INT_CURR("VEB ") /* Venezuelan Bolivar */
DEFINE_INT_CURR("VND ") /* Viet Nam Dong */
DEFINE_INT_CURR("VUV ") /* Vanuatu Vatu */
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("YDD ") /* Democratic Yemen */
DEFINE_INT_CURR("YER ") /* Yemen */
DEFINE_INT_CURR("YUD ") /* Yugoslavia */
DEFINE_INT_CURR("ZAL ") /* South Africa */
DEFINE_INT_CURR("ZAR ") /* Lesotho, Namibia */
DEFINE_INT_CURR("ZMK ") /* Zambia */
DEFINE_INT_CURR("ZRZ ") /* Zaire */
DEFINE_INT_CURR("ZWD ") /* Zimbabwe */
DEFINE_INT_CURR("YDD ") /* Yemini Dinar (Democratic Yemen) */
DEFINE_INT_CURR("YER ") /* Yemeni Rial */
DEFINE_INT_CURR("ZAR ") /* South Africa Rand (Lesotho, Namibia) */
DEFINE_INT_CURR("ZMK ") /* Zambian Kwacha */
DEFINE_INT_CURR("ZRZ ") /* Zaire Zaire */
DEFINE_INT_CURR("ZWD ") /* Zimbabwe Dollar */

View File

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

View File

@ -1167,19 +1167,131 @@ translations from the file
@end smallexample
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:
@c * message inheritence
@c * locale aliasing
@c * character set dependence
In the above example we assumed that the @code{LANGUAGE} environment
variable to @code{de}. This might be an appropriate selection but what
happens if the user wants to use @code{LC_ALL} because of the wider
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
@subsection Programs to handle message catalogs for @code{gettext}
@c Describe:
@c * msgfmt
@c * xgettext
@c Mention:
@c * other programs from GNU gettext
The GNU C Library does not contain the source code for the programs to
handle message catalogs for the @code{gettext} functions. As part of
the GNU project the GNU gettext package contains everything the
developer needs. The functionality provided by the tools in this
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 (-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, 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 <sys/types.h>
#include "../stdio-common/_itoa.h"
#include <stdio-common/_itoa.h>
/* Variable to synchronize work. */
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
in getopt. */
void
__getopt_clean_environment (void)
__getopt_clean_environment (char **env)
{
/* Bash 2.0 puts a special variable in the environment for each
command it runs, specifying which ARGV elements are the results
of file name wildcard expansion and therefore should not be
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 *cp, **ep;
size_t len;
@ -56,19 +56,19 @@ __getopt_clean_environment (void)
if (__libc_pid == 0)
__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,
sizeof (envvar_tail));
cp = _itoa_word (__libc_pid, cp, 10, 0);
*--cp = '_';
len = (var + sizeof (var) - 1) - cp;
for (ep = __environ; *ep != NULL; ++ep)
if (!strncmp (*ep, cp, len) && (*ep)[len] == '=')
for (ep = env; *ep != NULL; ++ep)
if (!strncmp (*ep, cp, len))
{
/* Found it. Store this pointer and move later ones back. */
char **dp = ep;
__getopt_nonoption_flags = &(*ep)[len + 1];
__getopt_nonoption_flags = &(*ep)[len];
do
dp[0] = dp[1];
while (*dp++);

View File

@ -252,6 +252,11 @@ extern char *alloca ();
#undef GLOB_PERIOD
#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,
int flags,
int (*errfunc) __P ((const char *, int)),

View File

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

View File

@ -57,20 +57,12 @@ static inline Elf32_Addr __attribute__ ((unused))
elf_machine_load_address (void)
{
Elf32_Addr addr;
asm (" call .Lhere\n"
".Lhere: popl %0\n"
" subl $.Lhere, %0"
asm (" call 1f\n"
"1: popl %0\n"
" subl 1b@GOT(%%ebx), %0"
: "=r" (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
/* 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 ("\
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function
.align 16
_dl_runtime_resolve:
pushl %eax # Preserve registers otherwise clobbered.
pushl %ecx
@ -147,6 +140,7 @@ _dl_runtime_resolve:
.globl _dl_runtime_profile
.type _dl_runtime_profile, @function
.align 16
_dl_runtime_profile:
pushl %eax # Preserve registers otherwise clobbered.
pushl %ecx
@ -167,6 +161,7 @@ _dl_runtime_profile:
.globl _dl_runtime_profile
.type _dl_runtime_resolve, @function
.type _dl_runtime_profile, @function
.align 16
_dl_runtime_resolve:
_dl_runtime_profile:
pushl %eax # Preserve registers otherwise clobbered.

View File

@ -73,6 +73,10 @@
#ifdef __GNUC__
#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
# define __MATH_INLINE __inline
#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
and/or argument range. */
@ -278,10 +356,10 @@ __inline_mathop (sqrt, "fsqrt")
__inline_mathop_ (long double, __sqrtl, "fsqrt")
#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 8)
__inline_mathcode_ (fabs, __x, return __builtin_fabs (__x))
__inline_mathcode_ (fabsf, __x, return __builtin_fabsf (__x))
__inline_mathcode_ (fabsl, __x, return __builtin_fabsl (__x))
__inline_mathcode_ (__fabsl, __x, return __builtin_fabsl (__x))
__inline_mathcode_ (double, fabs, __x, return __builtin_fabs (__x))
__inline_mathcode_ (float, fabsf, __x, return __builtin_fabsf (__x))
__inline_mathcode_ (long double, fabsl, __x, return __builtin_fabsl (__x))
__inline_mathcode_ (long double, __fabsl, __x, return __builtin_fabsl (__x))
#else
__inline_mathop (fabs, "fabs")
__inline_mathop_ (long double, __fabsl, "fabs")
@ -356,7 +434,7 @@ ldexp (double __x, int __y)
/* Optimized versions for some non-standardized functions. */
#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)
@ -443,15 +521,12 @@ __finite (double __x)
("orl $0x800fffff, %0\n\t"
"incl %0\n\t"
"shrl $31, %0"
: "=q" (__result) : "0" (((int *) &__x)[1]));
: "=q" (__result) : "0" (((int *) &__x)[1]) : "cc");
return __result;
}
/* Miscellaneous functions */
__inline_mathcode (__sgn, __x, \
return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0))
__inline_mathcode (__coshm1, __x, \
register long double __exm1 = __expm1l (__fabsl (__x)); \
return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1)
@ -459,69 +534,6 @@ __inline_mathcode (__coshm1, __x, \
__inline_mathcode (__acosh1p, __x, \
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 */
/* 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 __sincos_code
#endif /* Not gcc <= 2.7. */
#endif /* __NO_MATH_INLINES */
#endif /* __GNUC__ */

View File

@ -34,7 +34,7 @@ feraiseexcept (int excepts)
{
/* One example of a invalid operation is 0.0 / 0.0. */
double d;
__asm__ ("fldz; fdiv %%st, %%st(0); fwait" : "=t" (d));
__asm__ __volatile__ ("fldz; fdiv %%st, %%st(0); fwait" : "=t" (d));
(void) &d;
}
@ -42,7 +42,8 @@ feraiseexcept (int excepts)
if ((FE_DIVBYZERO & excepts) != 0)
{
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;
}
@ -55,16 +56,16 @@ feraiseexcept (int excepts)
/* Bah, we have to clear selected exceptions. Since there is no
`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. */
temp.status_word |= FE_OVERFLOW;
/* Put the new data in effect. */
__asm__ ("fldenv %0" : : "m" (*&temp));
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
/* And raise the exception. */
__asm__ ("fwait");
__asm__ __volatile__ ("fwait");
}
/* Next: underflow. */
@ -76,16 +77,16 @@ feraiseexcept (int excepts)
/* Bah, we have to clear selected exceptions. Since there is no
`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. */
temp.status_word |= FE_UNDERFLOW;
/* Put the new data in effect. */
__asm__ ("fldenv %0" : : "m" (*&temp));
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
/* And raise the exception. */
__asm__ ("fwait");
__asm__ __volatile__ ("fwait");
}
/* Last: inexact. */
@ -97,15 +98,15 @@ feraiseexcept (int excepts)
/* Bah, we have to clear selected exceptions. Since there is no
`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. */
temp.status_word |= FE_INEXACT;
/* Put the new data in effect. */
__asm__ ("fldenv %0" : : "m" (*&temp));
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
/* 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
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
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
#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 <math.h>
static void
ignore_me(double foo)
{
}
void
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
one signal at a time. It is important the if the overflow/underflow
exception and the inexact exception are given at the same time,
@ -37,30 +39,30 @@ feraiseexcept (int excepts)
if ((FE_INVALID & excepts) != 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. */
if ((FE_DIVBYZERO & excepts) != 0)
{
ignore_me (1.0 / 0.0);
sink = c.one / c.zero;
}
/* Next: overflow. */
if ((FE_OVERFLOW & excepts) != 0)
{
ignore_me (LDBL_MAX * LDBL_MAX);
sink = c.max * c.max;
}
/* Next: underflow. */
if ((FE_UNDERFLOW & excepts) != 0)
{
ignore_me (LDBL_MIN / 16.0);
sink = c.min / c.sixteen;
}
/* Last: inexact. */
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-udiv := 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)')\
define(OP,\`$(+divrem-OP-$(+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 $@
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>
#define ENV(reg) [%g1 + (reg * 4)]
ENTRY (__longjmp)
ENTRY(__longjmp)
/* Store our arguments in global registers so we can still
use them while unwinding frames and their register windows. */
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. */
mov 1, %g6 /* Delay slot only hit if zero: VAL = 1. */
mov 1, %g2 /* Delay slot only hit if zero: VAL = 1. */
0:
/* Cache target FP in register %g7. */
ld ENV (JB_FP), %g7
/* Cache target FP in register %g3. */
ld ENV(JB_FP), %g3
/* 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? */
bl,a loop /* Loop while current fp is below target. */
LOC(loop):
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. */
be,a found /* Better have hit it exactly. */
ld ENV (JB_SP), %o0 /* Delay slot: extract target SP. */
be,a LOC(found) /* Better have hit it exactly. */
ld ENV(JB_SP), %o0 /* Delay slot: extract target SP. */
bogus: /* Get here only if the jmp_buf or stack is clobbered. */
call C_SYMBOL_NAME (abort)
LOC(bogus):
/* Get here only if the jmp_buf or stack is clobbered. */
call C_SYMBOL_NAME(abort)
nop
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. */
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. */
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. */
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
! 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.
!
! 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
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
!
! 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
! 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 MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,205 +22,217 @@
! INPUT PARAMETERS
#define res_ptr %o0
#define s1_ptr %o1
#define s2_ptr %o2
#define size %o3
#define RES_PTR %o0
#define S1_PTR %o1
#define S2_PTR %o2
#define SIZE %o3
#include "sysdep.h"
#include <sysdep.h>
.text
.align 4
.global C_SYMBOL_NAME(__mpn_add_n)
C_SYMBOL_NAME(__mpn_add_n):
xor s2_ptr,res_ptr,%g1
ENTRY(__mpn_add_n)
xor S2_PTR,RES_PTR,%g1
andcc %g1,4,%g0
bne L1 ! branch if alignment differs
bne LOC(1) ! branch if alignment differs
nop
! ** V1a **
L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
be L_v1 ! if no, branch
LOC(0): andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
be LOC(v1) ! if no, branch
nop
/* Add least significant limb separately to align res_ptr and s2_ptr */
ld [s1_ptr],%g4
add s1_ptr,4,s1_ptr
ld [s2_ptr],%g2
add s2_ptr,4,s2_ptr
add size,-1,size
/* Add least significant limb separately to align RES_PTR and S2_PTR */
ld [S1_PTR],%g4
add S1_PTR,4,S1_PTR
ld [S2_PTR],%g2
add S2_PTR,4,S2_PTR
add SIZE,-1,SIZE
addcc %g4,%g2,%o4
st %o4,[res_ptr]
add res_ptr,4,res_ptr
L_v1: addx %g0,%g0,%o4 ! save cy in register
cmp size,2 ! if size < 2 ...
bl Lend2 ! ... branch to tail code
st %o4,[RES_PTR]
add RES_PTR,4,RES_PTR
LOC(v1):
addx %g0,%g0,%o4 ! save cy in register
cmp SIZE,2 ! if SIZE < 2 ...
bl LOC(end2) ! ... branch to tail code
subcc %g0,%o4,%g0 ! restore cy
ld [s1_ptr+0],%g4
addcc size,-10,size
ld [s1_ptr+4],%g1
ldd [s2_ptr+0],%g2
blt Lfin1
ld [S1_PTR+0],%g4
addcc SIZE,-10,SIZE
ld [S1_PTR+4],%g1
ldd [S2_PTR+0],%g2
blt LOC(fin1)
subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */
Loop1: addxcc %g4,%g2,%o4
ld [s1_ptr+8],%g4
addxcc %g1,%g3,%o5
ld [s1_ptr+12],%g1
ldd [s2_ptr+8],%g2
std %o4,[res_ptr+0]
LOC(loop1):
addxcc %g4,%g2,%o4
ld [s1_ptr+16],%g4
ld [S1_PTR+8],%g4
addxcc %g1,%g3,%o5
ld [s1_ptr+20],%g1
ldd [s2_ptr+16],%g2
std %o4,[res_ptr+8]
ld [S1_PTR+12],%g1
ldd [S2_PTR+8],%g2
std %o4,[RES_PTR+0]
addxcc %g4,%g2,%o4
ld [s1_ptr+24],%g4
ld [S1_PTR+16],%g4
addxcc %g1,%g3,%o5
ld [s1_ptr+28],%g1
ldd [s2_ptr+24],%g2
std %o4,[res_ptr+16]
ld [S1_PTR+20],%g1
ldd [S2_PTR+16],%g2
std %o4,[RES_PTR+8]
addxcc %g4,%g2,%o4
ld [s1_ptr+32],%g4
ld [S1_PTR+24],%g4
addxcc %g1,%g3,%o5
ld [s1_ptr+36],%g1
ldd [s2_ptr+32],%g2
std %o4,[res_ptr+24]
ld [S1_PTR+28],%g1
ldd [S2_PTR+24],%g2
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
addcc size,-8,size
add s1_ptr,32,s1_ptr
add s2_ptr,32,s2_ptr
add res_ptr,32,res_ptr
bge Loop1
addcc SIZE,-8,SIZE
add S1_PTR,32,S1_PTR
add S2_PTR,32,S2_PTR
add RES_PTR,32,RES_PTR
bge LOC(loop1)
subcc %g0,%o4,%g0 ! restore cy
Lfin1: addcc size,8-2,size
blt Lend1
LOC(fin1):
addcc SIZE,8-2,SIZE
blt LOC(end1)
subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 2 limbs until less than 2 limbs remain */
Loope1: addxcc %g4,%g2,%o4
ld [s1_ptr+8],%g4
LOC(loope1):
addxcc %g4,%g2,%o4
ld [S1_PTR+8],%g4
addxcc %g1,%g3,%o5
ld [s1_ptr+12],%g1
ldd [s2_ptr+8],%g2
std %o4,[res_ptr+0]
ld [S1_PTR+12],%g1
ldd [S2_PTR+8],%g2
std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size
add s1_ptr,8,s1_ptr
add s2_ptr,8,s2_ptr
add res_ptr,8,res_ptr
bge Loope1
addcc SIZE,-2,SIZE
add S1_PTR,8,S1_PTR
add S2_PTR,8,S2_PTR
add RES_PTR,8,RES_PTR
bge LOC(loope1)
subcc %g0,%o4,%g0 ! restore cy
Lend1: addxcc %g4,%g2,%o4
LOC(end1):
addxcc %g4,%g2,%o4
addxcc %g1,%g3,%o5
std %o4,[res_ptr+0]
std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register
andcc size,1,%g0
be Lret1
andcc SIZE,1,%g0
be LOC(ret1)
subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */
ld [s1_ptr+8],%g4
ld [s2_ptr+8],%g2
ld [S1_PTR+8],%g4
ld [S2_PTR+8],%g2
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
L1: xor s1_ptr,res_ptr,%g1
LOC(1): xor S1_PTR,RES_PTR,%g1
andcc %g1,4,%g0
bne L2
bne LOC(2)
nop
! ** V1b **
mov s2_ptr,%g1
mov s1_ptr,s2_ptr
b L0
mov %g1,s1_ptr
mov S2_PTR,%g1
mov S1_PTR,S2_PTR
b LOC(0)
mov %g1,S1_PTR
! ** V2 **
/* 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
/* 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
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
be Ljone
LOC(2): cmp SIZE,1
be LOC(jone)
nop
andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
be L_v2 ! if no, branch
andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
be LOC(v2) ! if no, branch
nop
/* Add least significant limb separately to align s1_ptr and s2_ptr */
ld [s1_ptr],%g4
add s1_ptr,4,s1_ptr
ld [s2_ptr],%g2
add s2_ptr,4,s2_ptr
add size,-1,size
/* Add least significant limb separately to align S1_PTR and S2_PTR */
ld [S1_PTR],%g4
add S1_PTR,4,S1_PTR
ld [S2_PTR],%g2
add S2_PTR,4,S2_PTR
add SIZE,-1,SIZE
addcc %g4,%g2,%o4
st %o4,[res_ptr]
add res_ptr,4,res_ptr
st %o4,[RES_PTR]
add RES_PTR,4,RES_PTR
L_v2: addx %g0,%g0,%o4 ! save cy in register
addcc size,-8,size
blt Lfin2
LOC(v2):
addx %g0,%g0,%o4 ! save cy in register
addcc SIZE,-8,SIZE
blt LOC(fin2)
subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */
Loop2: ldd [s1_ptr+0],%g2
ldd [s2_ptr+0],%o4
LOC(loop2):
ldd [S1_PTR+0],%g2
ldd [S2_PTR+0],%o4
addxcc %g2,%o4,%g2
st %g2,[res_ptr+0]
st %g2,[RES_PTR+0]
addxcc %g3,%o5,%g3
st %g3,[res_ptr+4]
ldd [s1_ptr+8],%g2
ldd [s2_ptr+8],%o4
st %g3,[RES_PTR+4]
ldd [S1_PTR+8],%g2
ldd [S2_PTR+8],%o4
addxcc %g2,%o4,%g2
st %g2,[res_ptr+8]
st %g2,[RES_PTR+8]
addxcc %g3,%o5,%g3
st %g3,[res_ptr+12]
ldd [s1_ptr+16],%g2
ldd [s2_ptr+16],%o4
st %g3,[RES_PTR+12]
ldd [S1_PTR+16],%g2
ldd [S2_PTR+16],%o4
addxcc %g2,%o4,%g2
st %g2,[res_ptr+16]
st %g2,[RES_PTR+16]
addxcc %g3,%o5,%g3
st %g3,[res_ptr+20]
ldd [s1_ptr+24],%g2
ldd [s2_ptr+24],%o4
st %g3,[RES_PTR+20]
ldd [S1_PTR+24],%g2
ldd [S2_PTR+24],%o4
addxcc %g2,%o4,%g2
st %g2,[res_ptr+24]
st %g2,[RES_PTR+24]
addxcc %g3,%o5,%g3
st %g3,[res_ptr+28]
st %g3,[RES_PTR+28]
addx %g0,%g0,%o4 ! save cy in register
addcc size,-8,size
add s1_ptr,32,s1_ptr
add s2_ptr,32,s2_ptr
add res_ptr,32,res_ptr
bge Loop2
addcc SIZE,-8,SIZE
add S1_PTR,32,S1_PTR
add S2_PTR,32,S2_PTR
add RES_PTR,32,RES_PTR
bge LOC(loop2)
subcc %g0,%o4,%g0 ! restore cy
Lfin2: addcc size,8-2,size
blt Lend2
LOC(fin2):
addcc SIZE,8-2,SIZE
blt LOC(end2)
subcc %g0,%o4,%g0 ! restore cy
Loope2: ldd [s1_ptr+0],%g2
ldd [s2_ptr+0],%o4
LOC(loope2):
ldd [S1_PTR+0],%g2
ldd [S2_PTR+0],%o4
addxcc %g2,%o4,%g2
st %g2,[res_ptr+0]
st %g2,[RES_PTR+0]
addxcc %g3,%o5,%g3
st %g3,[res_ptr+4]
st %g3,[RES_PTR+4]
addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size
add s1_ptr,8,s1_ptr
add s2_ptr,8,s2_ptr
add res_ptr,8,res_ptr
bge Loope2
addcc SIZE,-2,SIZE
add S1_PTR,8,S1_PTR
add S2_PTR,8,S2_PTR
add RES_PTR,8,RES_PTR
bge LOC(loope2)
subcc %g0,%o4,%g0 ! restore cy
Lend2: andcc size,1,%g0
be Lret2
LOC(end2):
andcc SIZE,1,%g0
be LOC(ret2)
subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */
Ljone: ld [s1_ptr],%g4
ld [s2_ptr],%g2
LOC(jone):
ld [S1_PTR],%g4
ld [S2_PTR],%g2
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
END(__mpn_add_n)

View File

@ -1,20 +1,20 @@
! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add
! 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.
!
! 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
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
!
! 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
! 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 MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,17 +22,14 @@
! INPUT PARAMETERS
! res_ptr o0
! s1_ptr o1
! size o2
! s2_limb o3
! RES_PTR o0
! S1_PTR o1
! SIZE o2
! S2_LIMB o3
#include "sysdep.h"
#include <sysdep.h>
.text
.align 4
.global C_SYMBOL_NAME(__mpn_addmul_1)
C_SYMBOL_NAME(__mpn_addmul_1):
ENTRY(__mpn_addmul_1)
! Make S1_PTR and RES_PTR point at the end of their blocks
! and put (- 4 x SIZE) in index/loop counter.
sll %o2,2,%o2
@ -41,19 +38,19 @@ C_SYMBOL_NAME(__mpn_addmul_1):
sub %g0,%o2,%o2
cmp %o3,0xfff
bgu Large
bgu LOC(large)
nop
ld [%o1+%o2],%o5
mov 0,%o0
b L0
b LOC(0)
add %o4,-4,%o4
Loop0:
LOC(loop0):
addcc %o5,%g1,%g1
ld [%o1+%o2],%o5
addx %o0,%g0,%o0
st %g1,[%o4+%o2]
L0: wr %g0,%o3,%y
LOC(0): wr %g0,%o3,%y
sra %o5,31,%g2
and %o3,%g2,%g2
andcc %g1,0,%g1
@ -79,7 +76,7 @@ L0: wr %g0,%o3,%y
addcc %g1,%o0,%g1
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter
bne Loop0
bne LOC(loop0)
ld [%o4+%o2],%o5
addcc %o5,%g1,%g1
@ -88,17 +85,18 @@ L0: wr %g0,%o3,%y
st %g1,[%o4+%o2]
Large: ld [%o1+%o2],%o5
LOC(large):
ld [%o1+%o2],%o5
mov 0,%o0
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
b L1
b LOC(1)
add %o4,-4,%o4
Loop:
LOC(loop):
addcc %o5,%g3,%g3
ld [%o1+%o2],%o5
addx %o0,%g0,%o0
st %g3,[%o4+%o2]
L1: wr %g0,%o5,%y
LOC(1): wr %g0,%o5,%y
and %o5,%g4,%g2
andcc %g0,%g0,%g1
mulscc %g1,%o3,%g1
@ -138,10 +136,12 @@ L1: wr %g0,%o5,%y
addcc %g3,%o0,%g3
addx %g2,%g1,%o0
addcc %o2,4,%o2
bne Loop
bne LOC(loop)
ld [%o4+%o2],%o5
addcc %o5,%g3,%g3
addx %o0,%g0,%o0
retl
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,
Boston, MA 02111-1307, USA. */
#include "sysdep.h"
#include <sysdep.h>
/* Code produced by Sun's C compiler calls this function with two extra
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. */
retl /* Return; the returned buffer leaves 96 */
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.
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. */
/* _setjmp is in setjmp.S */

View File

@ -1,40 +1 @@
/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. Sparc version.
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. */
/* setjmp is in setjmp.S */

View File

@ -47,8 +47,8 @@ define(V, `%o5')dnl
dnl
dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d
define(T, `%g1')dnl
define(SC, `%g7')dnl
ifelse(S, `true', `define(SIGN, `%g6')')dnl
define(SC, `%g2')dnl
ifelse(S, `true', `define(SIGN, `%g3')')dnl
dnl
dnl This is the recursive definition for developing quotient digits.
@ -65,7 +65,7 @@ dnl modified to reflect the output R.
dnl
define(DEVELOP_QUOTIENT_BITS,
` ! depth $1, accumulated bits $2
bl L.$1.eval(2**N+$2)
bl LOC($1.eval(2**N+$2))
srl V,1,V
! remainder is positive
subcc R,V,R
@ -73,7 +73,7 @@ define(DEVELOP_QUOTIENT_BITS,
` b 9f
add Q, ($2*2+1), Q
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')')
L.$1.eval(2**N+$2):
LOC($1.eval(2**N+$2)):
! remainder is negative
addcc R,V,R
ifelse($1, N,
@ -82,18 +82,10 @@ L.$1.eval(2**N+$2):
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')')
ifelse($1, 1, `9:')')dnl
#include "sysdep.h"
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sysdep.h>
#include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
FUNC(NAME)
ENTRY(NAME)
ifelse(S, `true',
` ! compute sign of result; if neither is negative, no problem
orcc divisor, dividend, %g0 ! either negative?
@ -124,11 +116,11 @@ ifelse(OP, `div',
1:
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
sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T
cmp R, T
blu Lnot_really_big
blu LOC(not_really_big)
clr ITER
! `Here the dividend is >= 2**(31-N) or so. We must be careful here,
@ -146,7 +138,7 @@ ifelse(OP, `div',
! Now compute SC.
2: addcc V, V, V
bcc Lnot_too_big
bcc LOC(not_too_big)
add SC, 1, SC
! We get here if the divisor overflowed while shifting.
@ -155,14 +147,14 @@ ifelse(OP, `div',
sll T, TOPBITS, T ! high order bit
srl V, 1, V ! rest of V
add V, T, V
b Ldo_single_div
b LOC(do_single_div)
sub SC, 1, SC
Lnot_too_big:
LOC(not_too_big):
3: cmp V, R
blu 2b
nop
be Ldo_single_div
be LOC(do_single_div)
nop
/* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */
@ -177,15 +169,15 @@ ifelse(OP, `div',
! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around.
! So we unroll slightly...
Ldo_single_div:
LOC(do_single_div):
subcc SC, 1, SC
bl Lend_regular_divide
bl LOC(end_regular_divide)
nop
sub R, V, R
mov 1, Q
b Lend_single_divloop
b LOC(end_single_divloop)
nop
Lsingle_divloop:
LOC(single_divloop):
sll Q, 1, Q
bl 1f
srl V, 1, V
@ -197,37 +189,37 @@ ifelse(OP, `div',
add R, V, R
sub Q, 1, Q
2:
Lend_single_divloop:
LOC(end_single_divloop):
subcc SC, 1, SC
bge Lsingle_divloop
bge LOC(single_divloop)
tst R
b,a Lend_regular_divide
b,a LOC(end_regular_divide)
Lnot_really_big:
LOC(not_really_big):
1:
sll V, N, V
cmp V, R
bleu 1b
addcc ITER, 1, ITER
be Lgot_result
be LOC(got_result)
sub ITER, 1, ITER
tst R ! set up for initial iteration
Ldivloop:
LOC(divloop):
sll Q, N, Q
DEVELOP_QUOTIENT_BITS(1, 0)
Lend_regular_divide:
LOC(end_regular_divide):
subcc ITER, 1, ITER
bge Ldivloop
bge LOC(divloop)
tst R
bl,a Lgot_result
bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!)
ifelse(OP, `div',
` sub Q, 1, Q
', ` add R, divisor, R
')
Lgot_result:
LOC(got_result):
ifelse(S, `true',
` ! check to see if answer should be < 0
tst SIGN
@ -236,3 +228,5 @@ ifelse(S, `true',
1:')
retl
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_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */
#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. */
@ -55,7 +55,7 @@ elf_machine_dynamic (void)
static inline Elf32_Addr
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
initialized at startup awaiting its RELATIVE fixup. */
@ -64,50 +64,187 @@ elf_machine_load_address (void)
".Load_address:\n\t"
"call 1f\n\t"
"or %1,%%lo(.Load_address),%1\n"
"1:\tld [%%l7+%1],%1"
: "=r"(pc), "=r"(got));
"1:\tld [%2+%1],%1"
: "=r"(pc), "=r"(got) : "r"(pic));
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 (
"add %%fp,0x44,%%o2\n\t" /* o2 = point to argc */
"ld [%%o2 - 4],%%o0\n\t" /* o0 = load argc */
"sll %%o0, 2, %%o0\n\t" /* o0 = argc * sizeof (int) */
"add %%o2,%%o0,%%o2\n\t" /* o2 = skip over argv */
"add %%o2,4,%%o2\n\t" /* skip over null after argv */
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);
/* Now %o2 is pointing to env, skip over that as well. */
"1:\n\t"
"ld [%%o2],%%o0\n\t"
"cmp %%o0,0\n\t"
"bnz 1b\n\t"
"add %%o2,4,%%o2\n\t"
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);
/* Note that above, we want to advance the NULL after envp so
we always add 4. */
/* The beginning of the PLT does:
/* Now, search for the AT_BASE property. */
"2:\n\t"
"ld [%%o2],%%o0\n\t"
"cmp %%o0,0\n\t"
"be,a 3f\n\t"
"or %%g0,%%g0,%0\n\t"
"cmp %%o0,7\n\t" /* AT_BASE = 7 */
"be,a 3f\n\t"
"ld [%%o2+4],%0\n\t"
"b 2b\n\t"
"add %%o2,8,%%o2\n\t"
/* At this point %0 has the load address for the interpreter */
"3:\n\t"
: "=r" (addr)
: /* no inputs */
: "o0", "o2");
return addr;
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_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 ("\
.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
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
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,
Elf32_Addr *const reloc_addr)
{
Elf32_Addr loadbase;
extern unsigned long _dl_hwcap;
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))
{
case R_SPARC_COPY:
#ifndef RTLD_BOOTSTRAP
if (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,
refsym->st_size));
#endif
break;
case R_SPARC_GLOB_DAT:
case R_SPARC_32:
*reloc_addr = value;
break;
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);
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;
case R_SPARC_8:
*(char *) reloc_addr = value;
@ -218,146 +363,3 @@ elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
}
#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.
*/
#include "sysdep.h"
#include <sysdep.h>
ENTRY(.mul)
mov %o0, %y ! multiplier -> Y
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
/*
@ -81,7 +83,7 @@ ENTRY(.mul)
! and put upper half in place
#endif
Lmul_shortway:
LOC(mul_shortway):
/*
* Short multiply. 12 steps, followed by a final shift step.
* 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
retl
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
/* For internal use only: access the fp state register. */
#define __fenv_stfsr(X) __asm__("stfsr %0" : "=m"(X))
#define __fenv_ldfsr(X) __asm__ __volatile__("ldfsr %0" : : "m"(X))
#define __fenv_stfsr(X) __asm__("st %%fsr,%0" : "=m"(X))
#define __fenv_ldfsr(X) __asm__ __volatile__("ld %0,%%fsr" : : "m"(X))

View File

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

View File

@ -1,19 +1,19 @@
! sparc __mpn_lshift --
! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
! Sparc __mpn_lshift --
!
! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library.
!
! 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
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
!
! 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
! 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 MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -21,17 +21,14 @@
! INPUT PARAMETERS
! res_ptr %o0
! src_ptr %o1
! size %o2
! cnt %o3
! RES_PTR %o0
! SRC_PTR %o1
! SIZE %o2
! CNT %o3
#include "sysdep.h"
#include <sysdep.h>
.text
.align 4
.global C_SYMBOL_NAME(__mpn_lshift)
C_SYMBOL_NAME(__mpn_lshift):
ENTRY(__mpn_lshift)
sll %o2,2,%g1
add %o1,%g1,%o1 ! make %o1 point at end of src
ld [%o1-4],%g2 ! load first limb
@ -40,12 +37,13 @@ C_SYMBOL_NAME(__mpn_lshift):
add %o2,-1,%o2
andcc %o2,4-1,%g4 ! number of limbs in first loop
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]
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 %o1,-4,%o1
addcc %g4,-1,%g4
@ -53,14 +51,15 @@ Loop0: ld [%o1-8],%g3
srl %g3,%o5,%g1
mov %g3,%g2
or %o4,%g1,%o4
bne Loop0
bne LOC(loop0)
st %o4,[%o0+0]
L0: tst %o2
be Lend
LOC(0): tst %o2
be LOC(end)
nop
Loop: ld [%o1-8],%g3
LOC(loop):
ld [%o1-8],%g3
add %o0,-16,%o0
addcc %o2,-4,%o2
sll %g2,%o3,%o4
@ -86,10 +85,13 @@ Loop: ld [%o1-8],%g3
add %o1,-16,%o1
or %g4,%g1,%g4
bne Loop
bne LOC(loop)
st %g4,[%o0+0]
Lend: sll %g2,%o3,%g2
LOC(end):
sll %g2,%o3,%g2
st %g2,[%o0-4]
retl
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
! 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.
!
! 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
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
!
! 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
! 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 MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,10 +22,10 @@
! INPUT PARAMETERS
! res_ptr o0
! s1_ptr o1
! size o2
! s2_limb o3
! RES_PTR o0
! S1_PTR o1
! SIZE o2
! S2_LIMB o3
! ADD CODE FOR SMALL MULTIPLIERS!
!1: ld
@ -89,12 +89,9 @@
! sll a,29,y2
! st x,
#include "sysdep.h"
#include <sysdep.h>
.text
.align 4
.global C_SYMBOL_NAME(__mpn_mul_1)
C_SYMBOL_NAME(__mpn_mul_1):
ENTRY(__mpn_mul_1)
! Make S1_PTR and RES_PTR point at the end of their blocks
! and put (- 4 x SIZE) in index/loop counter.
sll %o2,2,%o2
@ -103,16 +100,16 @@ C_SYMBOL_NAME(__mpn_mul_1):
sub %g0,%o2,%o2
cmp %o3,0xfff
bgu Large
bgu LOC(large)
nop
ld [%o1+%o2],%o5
mov 0,%o0
b L0
b LOC(0)
add %o4,-4,%o4
Loop0:
LOC(loop0):
st %g1,[%o4+%o2]
L0: wr %g0,%o3,%y
LOC(0): wr %g0,%o3,%y
sra %o5,31,%g2
and %o3,%g2,%g2
andcc %g1,0,%g1
@ -138,21 +135,22 @@ L0: wr %g0,%o3,%y
addcc %g1,%o0,%g1
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter
bne,a Loop0
bne,a LOC(loop0)
ld [%o1+%o2],%o5
retl
st %g1,[%o4+%o2]
Large: ld [%o1+%o2],%o5
LOC(large):
ld [%o1+%o2],%o5
mov 0,%o0
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
b L1
b LOC(1)
add %o4,-4,%o4
Loop:
LOC(loop):
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
andcc %g0,%g0,%g1
mulscc %g1,%o3,%g1
@ -192,8 +190,10 @@ L1: wr %g0,%o5,%y
addcc %g3,%o0,%g3
addx %g2,%g1,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter
bne,a Loop
bne,a LOC(loop)
ld [%o1+%o2],%o5
retl
st %g3,[%o4+%o2]
END(__mpn_mul_1)

View File

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

View File

@ -1,19 +1,19 @@
! 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.
!
! 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
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
!
! 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
! 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 MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -21,28 +21,26 @@
! INPUT PARAMETERS
! res_ptr %o0
! src_ptr %o1
! size %o2
! cnt %o3
! RES_PTR %o0
! SRC_PTR %o1
! SIZE %o2
! CNT %o3
#include "sysdep.h"
#include <sysdep.h>
.text
.align 4
.global C_SYMBOL_NAME(__mpn_rshift)
C_SYMBOL_NAME(__mpn_rshift):
ENTRY(__mpn_rshift)
ld [%o1],%g2 ! load first limb
sub %g0,%o3,%o5 ! negate shift count
add %o2,-1,%o2
andcc %o2,4-1,%g4 ! number of limbs in first loop
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]
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 %o1,4,%o1
addcc %g4,-1,%g4
@ -50,14 +48,15 @@ Loop0: ld [%o1+4],%g3
sll %g3,%o5,%g1
mov %g3,%g2
or %o4,%g1,%o4
bne Loop0
bne LOC(loop0)
st %o4,[%o0-4]
L0: tst %o2
be Lend
LOC(0): tst %o2
be LOC(end)
nop
Loop: ld [%o1+4],%g3
LOC(loop):
ld [%o1+4],%g3
add %o0,16,%o0
addcc %o2,-4,%o2
srl %g2,%o3,%o4
@ -83,10 +82,13 @@ Loop: ld [%o1+4],%g3
add %o1,16,%o1
or %g4,%g1,%g4
bne Loop
bne LOC(loop)
st %g4,[%o0-4]
Lend: srl %g2,%o3,%g2
LOC(end):
srl %g2,%o3,%g2
st %g2,[%o0-0]
retl
ld [%sp+80],%o0
END(__mpn_rshift)

View File

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

View File

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

View File

@ -27,54 +27,52 @@
! size o2
! s2_limb o3
#include "sysdep.h"
#include <sysdep.h>
.text
.align 4
.global C_SYMBOL_NAME(__mpn_addmul_1)
C_SYMBOL_NAME(__mpn_addmul_1):
orcc %g0,%g0,%g2
ENTRY(__mpn_addmul_1)
ld [%o1+0],%o4 ! 1
sll %o2,4,%g1
and %g1,(4-1)<<4,%g1
#if PIC
orcc %g0,%g0,%g2
mov %o7,%g4 ! Save return address register
call 1f
add %o7,LL-1f,%g3
1: mov %g4,%o7 ! Restore return address register
#else
sethi %hi(LL),%g3
or %g3,%lo(LL),%g3
#endif
jmp %g3+%g1
nop
LL:
LL00: add %o0,-4,%o0
b Loop00 /* 4, 8, 12, ... */
and %g1,(4-1)<<4,%g1
1: call 2f
add %o7,3f-1b,%g3
2: jmp %g3+%g1
mov %g4,%o7 ! Restore return address register
.align 4
3:
LOC(00):
add %o0,-4,%o0
b LOC(loop00) /* 4, 8, 12, ... */
add %o1,-4,%o1
nop
LL01: b Loop01 /* 1, 5, 9, ... */
LOC(01):
b LOC(loop01) /* 1, 5, 9, ... */
nop
nop
nop
LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
b Loop10
LOC(10):
add %o0,-12,%o0 /* 2, 6, 10, ... */
b LOC(loop10)
add %o1,4,%o1
nop
LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
b Loop11
LOC(11):
add %o0,-8,%o0 /* 3, 7, 11, ... */
b LOC(loop11)
add %o1,-8,%o1
nop
1: addcc %g3,%g2,%g3 ! 1
LOC(loop):
addcc %g3,%g2,%g3 ! 1
ld [%o1+4],%o4 ! 2
rd %y,%g2 ! 1
addx %g0,%g2,%g2
ld [%o0+0],%g1 ! 2
addcc %g1,%g3,%g3
st %g3,[%o0+0] ! 1
Loop00: umul %o4,%o3,%g3 ! 2
LOC(loop00):
umul %o4,%o3,%g3 ! 2
ld [%o0+4],%g1 ! 2
addxcc %g3,%g2,%g3 ! 2
ld [%o1+8],%o4 ! 3
@ -83,7 +81,8 @@ Loop00: umul %o4,%o3,%g3 ! 2
nop
addcc %g1,%g3,%g3
st %g3,[%o0+4] ! 2
Loop11: umul %o4,%o3,%g3 ! 3
LOC(loop11):
umul %o4,%o3,%g3 ! 3
addxcc %g3,%g2,%g3 ! 3
ld [%o1+12],%o4 ! 4
rd %y,%g2 ! 3
@ -92,7 +91,8 @@ Loop11: umul %o4,%o3,%g3 ! 3
ld [%o0+8],%g1 ! 2
addcc %g1,%g3,%g3
st %g3,[%o0+8] ! 3
Loop10: umul %o4,%o3,%g3 ! 4
LOC(loop10):
umul %o4,%o3,%g3 ! 4
addxcc %g3,%g2,%g3 ! 4
ld [%o1+0],%o4 ! 1
rd %y,%g2 ! 4
@ -102,8 +102,9 @@ Loop10: umul %o4,%o3,%g3 ! 4
st %g3,[%o0+12] ! 4
add %o0,16,%o0
addx %g0,%g2,%g2
Loop01: addcc %o2,-4,%o2
bg 1b
LOC(loop01):
addcc %o2,-4,%o2
bg LOC(loop)
umul %o4,%o3,%g3 ! 1
addcc %g3,%g2,%g3 ! 4
@ -112,13 +113,7 @@ Loop01: addcc %o2,-4,%o2
ld [%o0+0],%g1 ! 2
addcc %g1,%g3,%g3
st %g3,[%o0+0] ! 4
retl
addx %g0,%g2,%o0
retl
nop
! 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
! s2_limb o3
#include "sysdep.h"
#include <sysdep.h>
.text
.align 8
.global C_SYMBOL_NAME(__mpn_mul_1)
C_SYMBOL_NAME(__mpn_mul_1):
ENTRY(__mpn_mul_1)
sll %o2,4,%g1
and %g1,(4-1)<<4,%g1
#if PIC
mov %o7,%g4 ! Save return address register
call 1f
add %o7,LL-1f,%g3
1: mov %g4,%o7 ! Restore return address register
#else
sethi %hi(LL),%g3
or %g3,%lo(LL),%g3
#endif
and %g1,(4-1)<<4,%g1
1: call 2f
add %o7,3f-1b,%g3
2: mov %g4,%o7 ! Restore return address register
jmp %g3+%g1
ld [%o1+0],%o4 ! 1
LL:
LL00: add %o0,-4,%o0
.align 4
3:
LOC(00):
add %o0,-4,%o0
add %o1,-4,%o1
b Loop00 /* 4, 8, 12, ... */
b LOC(loop00) /* 4, 8, 12, ... */
orcc %g0,%g0,%g2
LL01: b Loop01 /* 1, 5, 9, ... */
LOC(01):
b LOC(loop01) /* 1, 5, 9, ... */
orcc %g0,%g0,%g2
nop
nop
LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
LOC(10):
add %o0,-12,%o0 /* 2, 6, 10, ... */
add %o1,4,%o1
b Loop10
b LOC(loop10)
orcc %g0,%g0,%g2
nop
LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
LOC(11):
add %o0,-8,%o0 /* 3, 7, 11, ... */
add %o1,-8,%o1
b Loop11
b LOC(loop11)
orcc %g0,%g0,%g2
Loop: addcc %g3,%g2,%g3 ! 1
LOC(loop):
addcc %g3,%g2,%g3 ! 1
ld [%o1+4],%o4 ! 2
st %g3,[%o0+0] ! 1
rd %y,%g2 ! 1
Loop00: umul %o4,%o3,%g3 ! 2
LOC(loop00):
umul %o4,%o3,%g3 ! 2
addxcc %g3,%g2,%g3 ! 2
ld [%o1+8],%o4 ! 3
st %g3,[%o0+4] ! 2
rd %y,%g2 ! 2
Loop11: umul %o4,%o3,%g3 ! 3
LOC(loop11):
umul %o4,%o3,%g3 ! 3
addxcc %g3,%g2,%g3 ! 3
ld [%o1+12],%o4 ! 4
add %o1,16,%o1
st %g3,[%o0+8] ! 3
rd %y,%g2 ! 3
Loop10: umul %o4,%o3,%g3 ! 4
LOC(loop10):
umul %o4,%o3,%g3 ! 4
addxcc %g3,%g2,%g3 ! 4
ld [%o1+0],%o4 ! 1
st %g3,[%o0+12] ! 4
add %o0,16,%o0
rd %y,%g2 ! 4
addx %g0,%g2,%g2
Loop01: addcc %o2,-4,%o2
bg Loop
LOC(loop01):
addcc %o2,-4,%o2
bg LOC(loop)
umul %o4,%o3,%g3 ! 1
addcc %g3,%g2,%g3 ! 4
st %g3,[%o0+0] ! 4
rd %y,%g2 ! 4
retl
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
! s2_limb o3
#include "sysdep.h"
#include <sysdep.h>
.text
.align 4
.global C_SYMBOL_NAME(__mpn_submul_1)
C_SYMBOL_NAME(__mpn_submul_1):
ENTRY(__mpn_submul_1)
sub %g0,%o2,%o2 ! negate ...
sll %o2,2,%o2 ! ... and scale size
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
Loop: ld [%o1+%o2],%o4
LOC(loop):
ld [%o1+%o2],%o4
ld [%g1+%o2],%g2
umul %o4,%o3,%o5
rd %y,%g3
@ -51,8 +49,10 @@ Loop: ld [%o1+%o2],%o4
st %g2,[%g1+%o2]
addcc %o2,4,%o2
bne Loop
bne LOC(loop)
nop
retl
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"
.text
.align 4
.global C_SYMBOL_NAME(__udiv_qrnnd)
C_SYMBOL_NAME(__udiv_qrnnd):
ENTRY(__udiv_qrnnd)
tst %o3
bneg Largedivisor
bneg LOC(largedivisor)
mov 8,%g1
b Lp1
b LOC(p1)
addxcc %o2,%o2,%o2
Lplop: bcc Ln1
LOC(plop):
bcc LOC(n1)
addxcc %o2,%o2,%o2
Lp1: addx %o1,%o1,%o1
LOC(p1):
addx %o1,%o1,%o1
subcc %o1,%o3,%o4
bcc Ln2
bcc LOC(n2)
addxcc %o2,%o2,%o2
Lp2: addx %o1,%o1,%o1
LOC(p2):
addx %o1,%o1,%o1
subcc %o1,%o3,%o4
bcc Ln3
bcc LOC(n3)
addxcc %o2,%o2,%o2
Lp3: addx %o1,%o1,%o1
LOC(p3):
addx %o1,%o1,%o1
subcc %o1,%o3,%o4
bcc Ln4
bcc LOC(n4)
addxcc %o2,%o2,%o2
Lp4: addx %o1,%o1,%o1
LOC(p4):
addx %o1,%o1,%o1
addcc %g1,-1,%g1
bne Lplop
bne LOC(plop)
subcc %o1,%o3,%o4
bcc Ln5
bcc LOC(n5)
addxcc %o2,%o2,%o2
Lp5: st %o1,[%o0]
LOC(p5):
st %o1,[%o0]
retl
xnor %g0,%o2,%o0
Lnlop: bcc Lp1
LOC(nlop):
bcc LOC(p1)
addxcc %o2,%o2,%o2
Ln1: addx %o4,%o4,%o4
LOC(n1):
addx %o4,%o4,%o4
subcc %o4,%o3,%o1
bcc Lp2
bcc LOC(p2)
addxcc %o2,%o2,%o2
Ln2: addx %o4,%o4,%o4
LOC(n2):
addx %o4,%o4,%o4
subcc %o4,%o3,%o1
bcc Lp3
bcc LOC(p3)
addxcc %o2,%o2,%o2
Ln3: addx %o4,%o4,%o4
LOC(n3):
addx %o4,%o4,%o4
subcc %o4,%o3,%o1
bcc Lp4
bcc LOC(p4)
addxcc %o2,%o2,%o2
Ln4: addx %o4,%o4,%o4
LOC(n4):
addx %o4,%o4,%o4
addcc %g1,-1,%g1
bne Lnlop
bne LOC(nlop)
subcc %o4,%o3,%o1
bcc Lp5
bcc LOC(p5)
addxcc %o2,%o2,%o2
Ln5: st %o4,[%o0]
LOC(n5):
st %o4,[%o0]
retl
xnor %g0,%o2,%o0
Largedivisor:
LOC(largedivisor):
and %o2,1,%o5 ! %o5 = n0 & 1
srl %o2,1,%o2
@ -98,89 +107,109 @@ Largedivisor:
srl %o3,1,%g3 ! %g3 = floor(d / 2)
add %g3,%g2,%g3 ! %g3 = ceil(d / 2)
b LLp1
b LOC(Lp1)
addxcc %o2,%o2,%o2
LLplop: bcc LLn1
LOC(Lplop):
bcc LOC(Ln1)
addxcc %o2,%o2,%o2
LLp1: addx %o1,%o1,%o1
LOC(Lp1):
addx %o1,%o1,%o1
subcc %o1,%g3,%o4
bcc LLn2
bcc LOC(Ln2)
addxcc %o2,%o2,%o2
LLp2: addx %o1,%o1,%o1
LOC(Lp2):
addx %o1,%o1,%o1
subcc %o1,%g3,%o4
bcc LLn3
bcc LOC(Ln3)
addxcc %o2,%o2,%o2
LLp3: addx %o1,%o1,%o1
LOC(Lp3):
addx %o1,%o1,%o1
subcc %o1,%g3,%o4
bcc LLn4
bcc LOC(Ln4)
addxcc %o2,%o2,%o2
LLp4: addx %o1,%o1,%o1
LOC(Lp4):
addx %o1,%o1,%o1
addcc %g1,-1,%g1
bne LLplop
bne LOC(Lplop)
subcc %o1,%g3,%o4
bcc LLn5
bcc LOC(Ln5)
addxcc %o2,%o2,%o2
LLp5: add %o1,%o1,%o1 ! << 1
LOC(Lp5):
add %o1,%o1,%o1 ! << 1
tst %g2
bne Oddp
bne LOC(Oddp)
add %o5,%o1,%o1
st %o1,[%o0]
retl
xnor %g0,%o2,%o0
LLnlop: bcc LLp1
LOC(Lnlop):
bcc LOC(Lp1)
addxcc %o2,%o2,%o2
LLn1: addx %o4,%o4,%o4
LOC(Ln1):
addx %o4,%o4,%o4
subcc %o4,%g3,%o1
bcc LLp2
bcc LOC(Lp2)
addxcc %o2,%o2,%o2
LLn2: addx %o4,%o4,%o4
LOC(Ln2):
addx %o4,%o4,%o4
subcc %o4,%g3,%o1
bcc LLp3
bcc LOC(Lp3)
addxcc %o2,%o2,%o2
LLn3: addx %o4,%o4,%o4
LOC(Ln3):
addx %o4,%o4,%o4
subcc %o4,%g3,%o1
bcc LLp4
bcc LOC(Lp4)
addxcc %o2,%o2,%o2
LLn4: addx %o4,%o4,%o4
LOC(Ln4):
addx %o4,%o4,%o4
addcc %g1,-1,%g1
bne LLnlop
bne LOC(Lnlop)
subcc %o4,%g3,%o1
bcc LLp5
bcc LOC(Lp5)
addxcc %o2,%o2,%o2
LLn5: add %o4,%o4,%o4 ! << 1
LOC(Ln5):
add %o4,%o4,%o4 ! << 1
tst %g2
bne Oddn
bne LOC(Oddn)
add %o5,%o4,%o4
st %o4,[%o0]
retl
xnor %g0,%o2,%o0
Oddp: xnor %g0,%o2,%o2
LOC(Oddp):
xnor %g0,%o2,%o2
! q' in %o2. r' in %o1
addcc %o1,%o2,%o1
bcc LLp6
bcc LOC(Lp6)
addx %o2,0,%o2
sub %o1,%o3,%o1
LLp6: subcc %o1,%o3,%g0
bcs LLp7
LOC(Lp6):
subcc %o1,%o3,%g0
bcs LOC(Lp7)
subx %o2,-1,%o2
sub %o1,%o3,%o1
LLp7: st %o1,[%o0]
LOC(Lp7):
st %o1,[%o0]
retl
mov %o2,%o0
Oddn: xnor %g0,%o2,%o2
LOC(Oddn):
xnor %g0,%o2,%o2
! q' in %o2. r' in %o4
addcc %o4,%o2,%o4
bcc LLn6
bcc LOC(Ln6)
addx %o2,0,%o2
sub %o4,%o3,%o4
LLn6: subcc %o4,%o3,%g0
bcs LLn7
LOC(Ln6):
subcc %o4,%o3,%g0
bcs LOC(Ln7)
subx %o2,-1,%o2
sub %o4,%o3,%o4
LLn7: st %o4,[%o0]
LOC(Ln7):
st %o4,[%o0]
retl
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
! store difference in a third limb vector.
!
! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
!
! This file is part of the GNU MP Library.
!
! 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
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
!
! 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
! 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 MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,290 +22,308 @@
! INPUT PARAMETERS
#define res_ptr %o0
#define s1_ptr %o1
#define s2_ptr %o2
#define size %o3
#define RES_PTR %o0
#define S1_PTR %o1
#define S2_PTR %o2
#define SIZE %o3
#include "sysdep.h"
#include <sysdep.h>
.text
.align 4
.global C_SYMBOL_NAME(__mpn_sub_n)
C_SYMBOL_NAME(__mpn_sub_n):
xor s2_ptr,res_ptr,%g1
ENTRY(__mpn_sub_n)
xor S2_PTR,RES_PTR,%g1
andcc %g1,4,%g0
bne L1 ! branch if alignment differs
bne LOC(1) ! branch if alignment differs
nop
! ** V1a **
andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
be L_v1 ! if no, branch
andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
be LOC(v1) ! if no, branch
nop
/* Add least significant limb separately to align res_ptr and s2_ptr */
ld [s1_ptr],%g4
add s1_ptr,4,s1_ptr
ld [s2_ptr],%g2
add s2_ptr,4,s2_ptr
add size,-1,size
/* Add least significant limb separately to align RES_PTR and S2_PTR */
ld [S1_PTR],%g4
add S1_PTR,4,S1_PTR
ld [S2_PTR],%g2
add S2_PTR,4,S2_PTR
add SIZE,-1,SIZE
subcc %g4,%g2,%o4
st %o4,[res_ptr]
add res_ptr,4,res_ptr
L_v1: addx %g0,%g0,%o4 ! save cy in register
cmp size,2 ! if size < 2 ...
bl Lend2 ! ... branch to tail code
st %o4,[RES_PTR]
add RES_PTR,4,RES_PTR
LOC(v1):
addx %g0,%g0,%o4 ! save cy in register
cmp SIZE,2 ! if SIZE < 2 ...
bl LOC(end2) ! ... branch to tail code
subcc %g0,%o4,%g0 ! restore cy
ld [s1_ptr+0],%g4
addcc size,-10,size
ld [s1_ptr+4],%g1
ldd [s2_ptr+0],%g2
blt Lfin1
ld [S1_PTR+0],%g4
addcc SIZE,-10,SIZE
ld [S1_PTR+4],%g1
ldd [S2_PTR+0],%g2
blt LOC(fin1)
subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */
Loop1: subxcc %g4,%g2,%o4
ld [s1_ptr+8],%g4
subxcc %g1,%g3,%o5
ld [s1_ptr+12],%g1
ldd [s2_ptr+8],%g2
std %o4,[res_ptr+0]
LOC(loop1):
subxcc %g4,%g2,%o4
ld [s1_ptr+16],%g4
ld [S1_PTR+8],%g4
subxcc %g1,%g3,%o5
ld [s1_ptr+20],%g1
ldd [s2_ptr+16],%g2
std %o4,[res_ptr+8]
ld [S1_PTR+12],%g1
ldd [S2_PTR+8],%g2
std %o4,[RES_PTR+0]
subxcc %g4,%g2,%o4
ld [s1_ptr+24],%g4
ld [S1_PTR+16],%g4
subxcc %g1,%g3,%o5
ld [s1_ptr+28],%g1
ldd [s2_ptr+24],%g2
std %o4,[res_ptr+16]
ld [S1_PTR+20],%g1
ldd [S2_PTR+16],%g2
std %o4,[RES_PTR+8]
subxcc %g4,%g2,%o4
ld [s1_ptr+32],%g4
ld [S1_PTR+24],%g4
subxcc %g1,%g3,%o5
ld [s1_ptr+36],%g1
ldd [s2_ptr+32],%g2
std %o4,[res_ptr+24]
ld [S1_PTR+28],%g1
ldd [S2_PTR+24],%g2
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
addcc size,-8,size
add s1_ptr,32,s1_ptr
add s2_ptr,32,s2_ptr
add res_ptr,32,res_ptr
bge Loop1
addcc SIZE,-8,SIZE
add S1_PTR,32,S1_PTR
add S2_PTR,32,S2_PTR
add RES_PTR,32,RES_PTR
bge LOC(loop1)
subcc %g0,%o4,%g0 ! restore cy
Lfin1: addcc size,8-2,size
blt Lend1
LOC(fin1):
addcc SIZE,8-2,SIZE
blt LOC(end1)
subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 2 limbs until less than 2 limbs remain */
Loope1: subxcc %g4,%g2,%o4
ld [s1_ptr+8],%g4
LOC(loope1):
subxcc %g4,%g2,%o4
ld [S1_PTR+8],%g4
subxcc %g1,%g3,%o5
ld [s1_ptr+12],%g1
ldd [s2_ptr+8],%g2
std %o4,[res_ptr+0]
ld [S1_PTR+12],%g1
ldd [S2_PTR+8],%g2
std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size
add s1_ptr,8,s1_ptr
add s2_ptr,8,s2_ptr
add res_ptr,8,res_ptr
bge Loope1
addcc SIZE,-2,SIZE
add S1_PTR,8,S1_PTR
add S2_PTR,8,S2_PTR
add RES_PTR,8,RES_PTR
bge LOC(loope1)
subcc %g0,%o4,%g0 ! restore cy
Lend1: subxcc %g4,%g2,%o4
LOC(end1):
subxcc %g4,%g2,%o4
subxcc %g1,%g3,%o5
std %o4,[res_ptr+0]
std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register
andcc size,1,%g0
be Lret1
andcc SIZE,1,%g0
be LOC(ret1)
subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */
ld [s1_ptr+8],%g4
ld [s2_ptr+8],%g2
ld [S1_PTR+8],%g4
ld [S2_PTR+8],%g2
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
L1: xor s1_ptr,res_ptr,%g1
LOC(1): xor S1_PTR,RES_PTR,%g1
andcc %g1,4,%g0
bne L2
bne LOC(2)
nop
! ** V1b **
andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
be L_v1b ! if no, branch
andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
be LOC(v1b) ! if no, branch
nop
/* Add least significant limb separately to align res_ptr and s1_ptr */
ld [s2_ptr],%g4
add s2_ptr,4,s2_ptr
ld [s1_ptr],%g2
add s1_ptr,4,s1_ptr
add size,-1,size
/* Add least significant limb separately to align RES_PTR and S1_PTR */
ld [S2_PTR],%g4
add S2_PTR,4,S2_PTR
ld [S1_PTR],%g2
add S1_PTR,4,S1_PTR
add SIZE,-1,SIZE
subcc %g2,%g4,%o4
st %o4,[res_ptr]
add res_ptr,4,res_ptr
L_v1b: addx %g0,%g0,%o4 ! save cy in register
cmp size,2 ! if size < 2 ...
bl Lend2 ! ... branch to tail code
st %o4,[RES_PTR]
add RES_PTR,4,RES_PTR
LOC(v1b):
addx %g0,%g0,%o4 ! save cy in register
cmp SIZE,2 ! if SIZE < 2 ...
bl LOC(end2) ! ... branch to tail code
subcc %g0,%o4,%g0 ! restore cy
ld [s2_ptr+0],%g4
addcc size,-10,size
ld [s2_ptr+4],%g1
ldd [s1_ptr+0],%g2
blt Lfin1b
ld [S2_PTR+0],%g4
addcc SIZE,-10,SIZE
ld [S2_PTR+4],%g1
ldd [S1_PTR+0],%g2
blt LOC(fin1b)
subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */
Loop1b: subxcc %g2,%g4,%o4
ld [s2_ptr+8],%g4
subxcc %g3,%g1,%o5
ld [s2_ptr+12],%g1
ldd [s1_ptr+8],%g2
std %o4,[res_ptr+0]
LOC(loop1b):
subxcc %g2,%g4,%o4
ld [s2_ptr+16],%g4
ld [S2_PTR+8],%g4
subxcc %g3,%g1,%o5
ld [s2_ptr+20],%g1
ldd [s1_ptr+16],%g2
std %o4,[res_ptr+8]
ld [S2_PTR+12],%g1
ldd [S1_PTR+8],%g2
std %o4,[RES_PTR+0]
subxcc %g2,%g4,%o4
ld [s2_ptr+24],%g4
ld [S2_PTR+16],%g4
subxcc %g3,%g1,%o5
ld [s2_ptr+28],%g1
ldd [s1_ptr+24],%g2
std %o4,[res_ptr+16]
ld [S2_PTR+20],%g1
ldd [S1_PTR+16],%g2
std %o4,[RES_PTR+8]
subxcc %g2,%g4,%o4
ld [s2_ptr+32],%g4
ld [S2_PTR+24],%g4
subxcc %g3,%g1,%o5
ld [s2_ptr+36],%g1
ldd [s1_ptr+32],%g2
std %o4,[res_ptr+24]
ld [S2_PTR+28],%g1
ldd [S1_PTR+24],%g2
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
addcc size,-8,size
add s1_ptr,32,s1_ptr
add s2_ptr,32,s2_ptr
add res_ptr,32,res_ptr
bge Loop1b
addcc SIZE,-8,SIZE
add S1_PTR,32,S1_PTR
add S2_PTR,32,S2_PTR
add RES_PTR,32,RES_PTR
bge LOC(loop1b)
subcc %g0,%o4,%g0 ! restore cy
Lfin1b: addcc size,8-2,size
blt Lend1b
LOC(fin1b):
addcc SIZE,8-2,SIZE
blt LOC(end1b)
subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 2 limbs until less than 2 limbs remain */
Loope1b:subxcc %g2,%g4,%o4
ld [s2_ptr+8],%g4
LOC(loope1b):
subxcc %g2,%g4,%o4
ld [S2_PTR+8],%g4
subxcc %g3,%g1,%o5
ld [s2_ptr+12],%g1
ldd [s1_ptr+8],%g2
std %o4,[res_ptr+0]
ld [S2_PTR+12],%g1
ldd [S1_PTR+8],%g2
std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size
add s1_ptr,8,s1_ptr
add s2_ptr,8,s2_ptr
add res_ptr,8,res_ptr
bge Loope1b
addcc SIZE,-2,SIZE
add S1_PTR,8,S1_PTR
add S2_PTR,8,S2_PTR
add RES_PTR,8,RES_PTR
bge LOC(loope1b)
subcc %g0,%o4,%g0 ! restore cy
Lend1b: subxcc %g2,%g4,%o4
LOC(end1b):
subxcc %g2,%g4,%o4
subxcc %g3,%g1,%o5
std %o4,[res_ptr+0]
std %o4,[RES_PTR+0]
addx %g0,%g0,%o4 ! save cy in register
andcc size,1,%g0
be Lret1b
andcc SIZE,1,%g0
be LOC(ret1b)
subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */
ld [s2_ptr+8],%g4
ld [s1_ptr+8],%g2
ld [S2_PTR+8],%g4
ld [S1_PTR+8],%g2
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
! ** V2 **
/* 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
/* 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
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
be Ljone
LOC(2): cmp SIZE,1
be LOC(jone)
nop
andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
be L_v2 ! if no, branch
andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
be LOC(v2) ! if no, branch
nop
/* Add least significant limb separately to align s1_ptr and s2_ptr */
ld [s1_ptr],%g4
add s1_ptr,4,s1_ptr
ld [s2_ptr],%g2
add s2_ptr,4,s2_ptr
add size,-1,size
/* Add least significant limb separately to align S1_PTR and S2_PTR */
ld [S1_PTR],%g4
add S1_PTR,4,S1_PTR
ld [S2_PTR],%g2
add S2_PTR,4,S2_PTR
add SIZE,-1,SIZE
subcc %g4,%g2,%o4
st %o4,[res_ptr]
add res_ptr,4,res_ptr
st %o4,[RES_PTR]
add RES_PTR,4,RES_PTR
L_v2: addx %g0,%g0,%o4 ! save cy in register
addcc size,-8,size
blt Lfin2
LOC(v2):
addx %g0,%g0,%o4 ! save cy in register
addcc SIZE,-8,SIZE
blt LOC(fin2)
subcc %g0,%o4,%g0 ! restore cy
/* Add blocks of 8 limbs until less than 8 limbs remain */
Loop2: ldd [s1_ptr+0],%g2
ldd [s2_ptr+0],%o4
LOC(loop2):
ldd [S1_PTR+0],%g2
ldd [S2_PTR+0],%o4
subxcc %g2,%o4,%g2
st %g2,[res_ptr+0]
st %g2,[RES_PTR+0]
subxcc %g3,%o5,%g3
st %g3,[res_ptr+4]
ldd [s1_ptr+8],%g2
ldd [s2_ptr+8],%o4
st %g3,[RES_PTR+4]
ldd [S1_PTR+8],%g2
ldd [S2_PTR+8],%o4
subxcc %g2,%o4,%g2
st %g2,[res_ptr+8]
st %g2,[RES_PTR+8]
subxcc %g3,%o5,%g3
st %g3,[res_ptr+12]
ldd [s1_ptr+16],%g2
ldd [s2_ptr+16],%o4
st %g3,[RES_PTR+12]
ldd [S1_PTR+16],%g2
ldd [S2_PTR+16],%o4
subxcc %g2,%o4,%g2
st %g2,[res_ptr+16]
st %g2,[RES_PTR+16]
subxcc %g3,%o5,%g3
st %g3,[res_ptr+20]
ldd [s1_ptr+24],%g2
ldd [s2_ptr+24],%o4
st %g3,[RES_PTR+20]
ldd [S1_PTR+24],%g2
ldd [S2_PTR+24],%o4
subxcc %g2,%o4,%g2
st %g2,[res_ptr+24]
st %g2,[RES_PTR+24]
subxcc %g3,%o5,%g3
st %g3,[res_ptr+28]
st %g3,[RES_PTR+28]
addx %g0,%g0,%o4 ! save cy in register
addcc size,-8,size
add s1_ptr,32,s1_ptr
add s2_ptr,32,s2_ptr
add res_ptr,32,res_ptr
bge Loop2
addcc SIZE,-8,SIZE
add S1_PTR,32,S1_PTR
add S2_PTR,32,S2_PTR
add RES_PTR,32,RES_PTR
bge LOC(loop2)
subcc %g0,%o4,%g0 ! restore cy
Lfin2: addcc size,8-2,size
blt Lend2
LOC(fin2):
addcc SIZE,8-2,SIZE
blt LOC(end2)
subcc %g0,%o4,%g0 ! restore cy
Loope2: ldd [s1_ptr+0],%g2
ldd [s2_ptr+0],%o4
LOC(loope2):
ldd [S1_PTR+0],%g2
ldd [S2_PTR+0],%o4
subxcc %g2,%o4,%g2
st %g2,[res_ptr+0]
st %g2,[RES_PTR+0]
subxcc %g3,%o5,%g3
st %g3,[res_ptr+4]
st %g3,[RES_PTR+4]
addx %g0,%g0,%o4 ! save cy in register
addcc size,-2,size
add s1_ptr,8,s1_ptr
add s2_ptr,8,s2_ptr
add res_ptr,8,res_ptr
bge Loope2
addcc SIZE,-2,SIZE
add S1_PTR,8,S1_PTR
add S2_PTR,8,S2_PTR
add RES_PTR,8,RES_PTR
bge LOC(loope2)
subcc %g0,%o4,%g0 ! restore cy
Lend2: andcc size,1,%g0
be Lret2
LOC(end2):
andcc SIZE,1,%g0
be LOC(ret2)
subcc %g0,%o4,%g0 ! restore cy
/* Add last limb */
Ljone: ld [s1_ptr],%g4
ld [s2_ptr],%g2
LOC(jone):
ld [S1_PTR],%g4
ld [S2_PTR],%g2
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
END(__mpn_sub_n)

View File

@ -1,20 +1,20 @@
! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
! 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.
!
! 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
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
!
! 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
! 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 MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@ -22,17 +22,14 @@
! INPUT PARAMETERS
! res_ptr o0
! s1_ptr o1
! size o2
! s2_limb o3
! RES_PTR o0
! S1_PTR o1
! SIZE o2
! S2_LIMB o3
#include "sysdep.h"
#include <sysdep.h>
.text
.align 4
.global C_SYMBOL_NAME(__mpn_submul_1)
C_SYMBOL_NAME(__mpn_submul_1):
ENTRY(__mpn_submul_1)
! Make S1_PTR and RES_PTR point at the end of their blocks
! and put (- 4 x SIZE) in index/loop counter.
sll %o2,2,%o2
@ -41,19 +38,19 @@ C_SYMBOL_NAME(__mpn_submul_1):
sub %g0,%o2,%o2
cmp %o3,0xfff
bgu Large
bgu LOC(large)
nop
ld [%o1+%o2],%o5
mov 0,%o0
b L0
b LOC(0)
add %o4,-4,%o4
Loop0:
LOC(loop0):
subcc %o5,%g1,%g1
ld [%o1+%o2],%o5
addx %o0,%g0,%o0
st %g1,[%o4+%o2]
L0: wr %g0,%o3,%y
LOC(0): wr %g0,%o3,%y
sra %o5,31,%g2
and %o3,%g2,%g2
andcc %g1,0,%g1
@ -79,7 +76,7 @@ L0: wr %g0,%o3,%y
addcc %g1,%o0,%g1
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter
bne Loop0
bne LOC(loop0)
ld [%o4+%o2],%o5
subcc %o5,%g1,%g1
@ -88,17 +85,18 @@ L0: wr %g0,%o3,%y
st %g1,[%o4+%o2]
Large: ld [%o1+%o2],%o5
LOC(large):
ld [%o1+%o2],%o5
mov 0,%o0
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
b L1
b LOC(1)
add %o4,-4,%o4
Loop:
LOC(loop):
subcc %o5,%g3,%g3
ld [%o1+%o2],%o5
addx %o0,%g0,%o0
st %g3,[%o4+%o2]
L1: wr %g0,%o5,%y
LOC(1): wr %g0,%o5,%y
and %o5,%g4,%g2
andcc %g0,%g0,%g1
mulscc %g1,%o3,%g1
@ -138,10 +136,12 @@ L1: wr %g0,%o5,%y
addcc %g3,%o0,%g3
addx %g2,%g1,%o0
addcc %o2,4,%o2
bne Loop
bne LOC(loop)
ld [%o4+%o2],%o5
subcc %o5,%g3,%g3
addx %o0,%g0,%o0
retl
st %g3,[%o4+%o2]
END(__mpn_submul_1)

View File

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

View File

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

View File

@ -14,13 +14,14 @@
* bnz overflow (or tnz)
*/
#include "DEFS.h"
FUNC(.umul)
#include <sysdep.h>
ENTRY(.umul)
or %o0, %o1, %o4
mov %o0, %y ! multiplier -> Y
andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
be Lmul_shortway ! if zero, can do it the short way
andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
be LOC(mul_shortway) ! if zero, can do it the short way
andcc %g0, %g0, %o4 ! zero the partial product; clear N & V
/*
* Long multiply. 32 steps, followed by a final shift step.
@ -59,7 +60,6 @@ FUNC(.umul)
mulscc %o4, %o1, %o4 ! 32
mulscc %o4, %g0, %o4 ! final shift
/*
* Normally, with the shift-and-add approach, if both numbers are
* positive you get the correct result. With 32-bit two's-complement
@ -110,7 +110,7 @@ FUNC(.umul)
addcc %o4, %o2, %o1 ! add compensation and put upper half in place
#endif
Lmul_shortway:
LOC(mul_shortway):
/*
* Short multiply. 12 steps, followed by a final shift step.
* The resulting bits are off by 12 and (32-12) = 20 bit positions,
@ -151,3 +151,5 @@ Lmul_shortway:
or %o5, %o0, %o0
retl
addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
END(.umul)

View File

@ -37,16 +37,8 @@
#include "sysdep.h"
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sysdep.h>
#include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
ENTRY(.urem)
@ -63,11 +55,11 @@ ENTRY(.urem)
1:
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
sethi %hi(1 << (32 - 4 - 1)), %g1
cmp %o3, %g1
blu Lnot_really_big
blu LOC(not_really_big)
clr %o4
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
@ -78,15 +70,15 @@ ENTRY(.urem)
1:
cmp %o5, %g1
bgeu 3f
mov 1, %g7
mov 1, %g2
sll %o5, 4, %o5
b 1b
add %o4, 1, %o4
! Now compute %g7.
! Now compute %g2.
2: addcc %o5, %o5, %o5
bcc Lnot_too_big
add %g7, 1, %g7
bcc LOC(not_too_big)
add %g2, 1, %g2
! We get here if the %o1 overflowed while shifting.
! This means that %o3 has the high-order bit set.
@ -94,20 +86,20 @@ ENTRY(.urem)
sll %g1, 4, %g1 ! high order bit
srl %o5, 1, %o5 ! rest of %o5
add %o5, %g1, %o5
b Ldo_single_div
sub %g7, 1, %g7
b LOC(do_single_div)
sub %g2, 1, %g2
Lnot_too_big:
LOC(not_too_big):
3: cmp %o5, %o3
blu 2b
nop
be Ldo_single_div
be LOC(do_single_div)
nop
/* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */
! %o5 > %o3: went too far: back up 1 step
! srl %o5, 1, %o5
! dec %g7
! dec %g2
! do single-bit divide steps
!
! 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
! division loop will mess up the first time around.
! So we unroll slightly...
Ldo_single_div:
subcc %g7, 1, %g7
bl Lend_regular_divide
LOC(do_single_div):
subcc %g2, 1, %g2
bl LOC(end_regular_divide)
nop
sub %o3, %o5, %o3
mov 1, %o2
b Lend_single_divloop
b LOC(end_single_divloop)
nop
Lsingle_divloop:
LOC(single_divloop):
sll %o2, 1, %o2
bl 1f
srl %o5, 1, %o5
@ -136,66 +128,66 @@ ENTRY(.urem)
add %o3, %o5, %o3
sub %o2, 1, %o2
2:
Lend_single_divloop:
subcc %g7, 1, %g7
bge Lsingle_divloop
LOC(end_single_divloop):
subcc %g2, 1, %g2
bge LOC(single_divloop)
tst %o3
b,a Lend_regular_divide
b,a LOC(end_regular_divide)
Lnot_really_big:
LOC(not_really_big):
1:
sll %o5, 4, %o5
cmp %o5, %o3
bleu 1b
addcc %o4, 1, %o4
be Lgot_result
be LOC(got_result)
sub %o4, 1, %o4
tst %o3 ! set up for initial iteration
Ldivloop:
LOC(divloop):
sll %o2, 4, %o2
! depth 1, accumulated bits 0
bl L.1.16
bl LOC(1.16)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 2, accumulated bits 1
bl L.2.17
bl LOC(2.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits 3
bl L.3.19
bl LOC(3.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 7
bl L.4.23
bl LOC(4.23)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (7*2+1), %o2
L.4.23:
LOC(4.23):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (7*2-1), %o2
L.3.19:
LOC(3.19):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 5
bl L.4.21
bl LOC(4.21)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (5*2+1), %o2
L.4.21:
LOC(4.21):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@ -203,41 +195,41 @@ L.4.21:
L.2.17:
LOC(2.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits 1
bl L.3.17
bl LOC(3.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 3
bl L.4.19
bl LOC(4.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (3*2+1), %o2
L.4.19:
LOC(4.19):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (3*2-1), %o2
L.3.17:
LOC(3.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 1
bl L.4.17
bl LOC(4.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (1*2+1), %o2
L.4.17:
LOC(4.17):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@ -246,46 +238,46 @@ L.4.17:
L.1.16:
LOC(1.16):
! remainder is negative
addcc %o3,%o5,%o3
! depth 2, accumulated bits -1
bl L.2.15
bl LOC(2.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits -1
bl L.3.15
bl LOC(3.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -1
bl L.4.15
bl LOC(4.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-1*2+1), %o2
L.4.15:
LOC(4.15):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-1*2-1), %o2
L.3.15:
LOC(3.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -3
bl L.4.13
bl LOC(4.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-3*2+1), %o2
L.4.13:
LOC(4.13):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@ -293,41 +285,41 @@ L.4.13:
L.2.15:
LOC(2.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits -3
bl L.3.13
bl LOC(3.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -5
bl L.4.11
bl LOC(4.11)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-5*2+1), %o2
L.4.11:
LOC(4.11):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-5*2-1), %o2
L.3.13:
LOC(3.13):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -7
bl L.4.9
bl LOC(4.9)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-7*2+1), %o2
L.4.9:
LOC(4.9):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@ -337,16 +329,18 @@ L.4.9:
9:
Lend_regular_divide:
LOC(end_regular_divide):
subcc %o4, 1, %o4
bge Ldivloop
bge LOC(divloop)
tst %o3
bl,a Lgot_result
bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!)
add %o3, %o1, %o3
Lgot_result:
LOC(got_result):
retl
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. */
#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
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)
{
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
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;
@ -248,9 +255,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
.type _dl_runtime_resolve, @function
_dl_runtime_resolve:
save %sp, -160, %sp
mov %g5, %o0
mov %g1, %o0
call fixup
mov %g6, %o1
mov %g2, %o1
jmp %o0
restore
.size _dl_runtime_resolve, .-_dl_runtime_resolve

View File

@ -41,13 +41,11 @@
/* Now two recommended cw */
/* Linux default:
/* Linux and IEEE default:
- extended precision
- rounding to nearest
- no exceptions */
#define _FPU_DEFAULT 0x0
/* IEEE: same as above */
#define _FPU_IEEE 0x0
/* 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. */
asm volatile( "movw %%ds,%0 ; movw %0,%%ds
movw %%es,%0 ; movw %0,%%es
movw %%fs,%0 ; movw %0,%%fs
movw %%gs,%0 ; movw %0,%%gs
movw %%ss,%0 ; movw %0,%%ss"
asm volatile( "movw %%ds,%0 ; movw %0,%%ds\n"
"movw %%es,%0 ; movw %0,%%es\n"
"movw %%fs,%0 ; movw %0,%%fs\n"
"movw %%gs,%0 ; movw %0,%%gs\n"
"movw %%ss,%0 ; movw %0,%%ss"
: "=r" (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.
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
On-Line Applications Research Corporation.
@ -157,9 +157,9 @@ struct i80960ca_ctltbl {
#define clear_intr( xint ) \
{ register unsigned32 _xint=(xint); \
asm volatile( "loop_til_cleared:
clrbit %0,sf0,sf0 ; \
bbs %0,sf0,loop_til_cleared" \
asm volatile( "loop_til_cleared:" \
" clrbit %0,sf0,sf0 ;" \
" bbs %0,sf0,loop_til_cleared" \
: "=d" (_xint) : "0" (_xint) ); \
}

View File

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

View File

@ -74,24 +74,19 @@ ENTRY(____sparc_signal_trampoline)
1:
#ifdef PIC
/* Save return address */
mov %o7,%o4
___sxx:
call ___syy
nop
___syy:
sethi %hi(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
or %o5,%lo(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
add %o7,%o5,%o5
mov %o7,%o5
11: call 12f
sethi %hi(_GLOBAL_OFFSET_TABLE_-(11b-.)),%o4
12: or %o5,%lo(_GLOBAL_OFFSET_TABLE_-(11b-.)),%o4
add %o7,%o4,%o4
/* restore return address */
mov %o4,%o7
mov %o5,%o4
mov %o5,%o7
/* o4 has the GOT pointer */
#endif
sethi %hi(C_SYMBOL_NAME(____sig_table)),%o5
or %o5,%lo(C_SYMBOL_NAME(____sig_table)),%o5
#ifdef PIC
add %o5,%o4,%o4
ld [%o4],%o5
ld [%o4+%o5], %o5
#endif
sll %o0,2,%o4
add %o5,%o4,%o4
@ -141,3 +136,5 @@ ___syy:
/* if we return, sysreturn failed */
mov SYS_ify(exit),%g1
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
of program start, or having dlopen pass them in. */
#define SYSDEP_CALL_INIT(NAME, INIT) \
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); \
}
#include <sysdep.h>
#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,23 +36,30 @@
/* Linux/SPARC uses a different trap number */
#undef PSEUDO
#undef ENTRY
#undef END
#undef LOC
#define ENTRY(name) \
.global C_SYMBOL_NAME(name); \
.align 2;\
.align 4;\
C_LABEL(name);\
.type name,@function;
#define END(name) \
.size name, . - name
#define LOC(name) . ## L ## name
#ifdef PIC
#define SYSCALL_ERROR_HANDLER \
.global C_SYMBOL_NAME(__errno_location);\
.type C_SYMBOL_NAME(__errno_location),@function;\
save %sp,-96,%sp;\
call __errno_location;\
nop;\
st %i0,[%o0];\
restore;\
retl;\
.global C_SYMBOL_NAME(__errno_location); \
.type C_SYMBOL_NAME(__errno_location),@function; \
save %sp,-96,%sp; \
call __errno_location; \
nop; \
st %i0,[%o0]; \
restore; \
retl; \
mov -1,%o0;
#else
#define SYSCALL_ERROR_HANDLER \
@ -70,10 +77,10 @@
ENTRY(name); \
LOADSYSCALL(syscall_name); \
ta 0x10; \
bcc,a 1f; \
bcc,a 9000f; \
nop; \
SYSCALL_ERROR_HANDLER; \
1:;
9000:;
#endif /* ASSEMBLER */

View File

@ -42,7 +42,7 @@ typedef signed long int __int64_t;
typedef unsigned long int __uint64_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 __gid_t; /* Type of group identifications. */
typedef __u_int __ino_t; /* Type of file serial numbers. */

View File

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