mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-28 00:21:52 +03:00
Update.
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:
182
ChangeLog
182
ChangeLog
@ -1,3 +1,181 @@
|
|||||||
|
1997-08-24 12:24 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* configure.in (INSTALL): Quote `$'.
|
||||||
|
|
||||||
|
* libc.map: Add __xpg_basename.
|
||||||
|
|
||||||
|
* csu/Makefile (initfini.s): Disable optimization.
|
||||||
|
|
||||||
|
* elf/dl-deps.c: Implement handling of DL_FILTER.
|
||||||
|
|
||||||
|
* elf/dl-load.c (_dl_init_paths): Add error check.
|
||||||
|
|
||||||
|
* intl/finddomain.c (_nl_find_domain): Correct comment.
|
||||||
|
* intl/localealias.c: Include <bits/libc-lock.h> not <libc-lock.h>.
|
||||||
|
|
||||||
|
* libio/stdio.h: Make {,v}snprintf available if __USE_BSD.
|
||||||
|
Change extern inline functions to work correctly in C++.
|
||||||
|
|
||||||
|
* locale/iso-4217.def: Update for more recent ISO 4217 version.
|
||||||
|
|
||||||
|
* locale/loadlocale.c (_nl_load_locale): Add cast.
|
||||||
|
|
||||||
|
* manual/message.texi: Finish gettext section.
|
||||||
|
|
||||||
|
* posix/getopt_init.c: Don't use relative #include path.
|
||||||
|
(__getopt_clean_environment): Change function to take pointer to
|
||||||
|
environment as argument. Optimize generation of test string a bit.
|
||||||
|
* sysdeps/unix/sysv/linux/init-first.c: Call __getopt_clean_environment
|
||||||
|
with additional argument.
|
||||||
|
|
||||||
|
* poisx/glob.c: Add prototype for next_brace_sub.
|
||||||
|
|
||||||
|
* sysdeps/generic/dl-sysdep.c: Recognize AT_BASE value on auxiliary
|
||||||
|
vector.
|
||||||
|
|
||||||
|
* sysdeps/i386/dl-machine.h (elf_machine_load_address): Rewrite
|
||||||
|
to not generate relocation entry. Suggested by Richard Henderson.
|
||||||
|
(ELF_MACHINE_BEFORE_RTLD_RELOC): Removed.
|
||||||
|
(elf_machine_runtime_setup): Add .aligns.
|
||||||
|
|
||||||
|
* sysdeps/i386/fpu/fraiseexcpt.c: Add volatile to asms.
|
||||||
|
|
||||||
|
* sysdeps/i386/fpu/bits/mathinline.h: Partially undo change of
|
||||||
|
1997-08-14 03:14. gcc 2.7.2* is really broken in some aspects.
|
||||||
|
|
||||||
|
* sysdeps/standalone/i386/i386.h: Clean up asm statements a bit.
|
||||||
|
* sysdeps/standalone/i960/i960ca.h: Likewise.
|
||||||
|
|
||||||
|
1997-08-22 19:04 Richard Henderson <rth@cygnus.com>
|
||||||
|
|
||||||
|
* elf/rtld.c (_dl_start): Init _dl_rtld_map.l_opencount due to
|
||||||
|
undocumented test addition in _dl_map_object.
|
||||||
|
|
||||||
|
Support ET_EXEC versions of ld.so, for debugging at least:
|
||||||
|
|
||||||
|
* elf/dl-load.c (_dl_map_object): Add_name_to_object could get
|
||||||
|
called despite the DT_SONAME != NULL test, segfaulting. Simplify
|
||||||
|
the code here as well.
|
||||||
|
* elf/dl-lookup.c (do_lookup): Skip objects with no symtab.
|
||||||
|
(_dl_setup_hash): Likewise for hash tables.
|
||||||
|
* elf/dl-version.c (_dl_check_map_versions): Likewise for strtabs.
|
||||||
|
* elf/rtld.c (_dl_start): Likewise for rpath.
|
||||||
|
(_dl_rtld_libname2): New variable.
|
||||||
|
(dl_main): Use it to add an soname for ourselves when we don't have
|
||||||
|
one of our own. Base it on the target's .interp.
|
||||||
|
(dl_main): Again, skip printing of objects that don't have strtabs.
|
||||||
|
|
||||||
|
Sparc 32 merge:
|
||||||
|
|
||||||
|
* elf/dl-runtime.c (ELF_FIXUP_RETURN_VALUE): Provide default value.
|
||||||
|
(fixup): Simplify code. Use ELF_FIXUP_RETURN_VALUE.
|
||||||
|
(profile_fixup): Likewise, though this still needs fixing for
|
||||||
|
Sparc32 and PPC.
|
||||||
|
* sysdeps/powerpc/dl-machine.h: Transmute ELF_FIXUP_RETURNS_ADDRESS
|
||||||
|
to ELF_FIXUP_RETURN_VALUE.
|
||||||
|
|
||||||
|
* sysdeps/sparc/sparc32/dl-machine.h: Implement lazy relocation.
|
||||||
|
Fix up _dl_start_user to handle _dl_skip_args properly.
|
||||||
|
Use _dl_hwcap to determine if "flush" is available/needed.
|
||||||
|
|
||||||
|
* sysdeps/sparc/configure.in: Remove. It doesn't actually do
|
||||||
|
anything anymore, and what it did do is done somewhere else.
|
||||||
|
* sysdeps/sparc/configure: Likewise.
|
||||||
|
|
||||||
|
* sysdeps/sparc/fpu/bits/mathdef.h (FP_ILOGB0, FP_ILOGBNAN): New.
|
||||||
|
|
||||||
|
* sysdeps/sparc/fpu/fraiseexcpt.c: Rearrange for smaller code.
|
||||||
|
|
||||||
|
* sysdeps/sparc/sparc32/Makefile: Fix sparc->sparc/sparc32 bits
|
||||||
|
in divrem expansions.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h (END, LOC): New
|
||||||
|
definitions for assembly syntax differences.
|
||||||
|
|
||||||
|
* sysdeps/sparc/sparc32/__longjmp.S: %g6,%g7 are reserved to the
|
||||||
|
"system". Use %g2,%g3 instead. Use new local label macro.
|
||||||
|
* sysdeps/sparc/sparc32/add_n.S: Use <sysdep.h> and ENTRY, END,
|
||||||
|
and LOC for proper assembly headers/footers.
|
||||||
|
* sysdeps/sparc/sparc32/addmul_1.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/alloca.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/dotmul.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/lshift.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/mul_1.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/rshift.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/addmul_1.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/mul_1.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/submul_1.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/sub_n.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/submul_1.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/udiv_qrnnd.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/umul.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/divrem.m4: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/rem.S: Regenerate.
|
||||||
|
* sysdeps/sparc/sparc32/sdiv.S: Regenerate.
|
||||||
|
* sysdeps/sparc/sparc32/udiv.S: Regenerate.
|
||||||
|
* sysdeps/sparc/sparc32/urem.S: Regenerate.
|
||||||
|
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/dotmul.S: New file.
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/rem.S: New file.
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/sdiv.S: New file.
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/udiv.S: New file.
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/umul.S: New file.
|
||||||
|
* sysdeps/sparc/sparc32/sparcv8/urem.S: New file.
|
||||||
|
|
||||||
|
* sysdeps/sparc/sparc32/bsd-_setjmp.S: Dike out.
|
||||||
|
* sysdeps/sparc/sparc32/bsd-setjmp.S: Likewise.
|
||||||
|
* sysdeps/sparc/sparc32/setjmp.S: Add _setjmp and setjmp entry points.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/sparc32/__sigtrampoline.S:
|
||||||
|
Clean up PIC code.
|
||||||
|
|
||||||
|
* sysdeps/sparc/sparc32/elf/start.S: New file, slightly modified
|
||||||
|
from the sparc64 version.
|
||||||
|
* sysdeps/sparc/sparc32/elf/start.c: Removed.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/sparc32/init-first.h: Rewrite in
|
||||||
|
assembly based on the sparc64 version.
|
||||||
|
|
||||||
|
* sysdeps/sparc/sparc32/fpu/bits/fenv.h: Duh. Use proper syntax
|
||||||
|
for manipulating %fsr.
|
||||||
|
* sysdeps/sparc/sparc32/fpu/fpu_control.h: Make IEEE conformance
|
||||||
|
be the default.
|
||||||
|
|
||||||
|
* elf/elf.h (HWCAP_SPARC_*): New definitions.
|
||||||
|
* elf/rtld.c (_dl_hwcap): New variable.
|
||||||
|
* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Record AT_HWCAP.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c: New file.
|
||||||
|
Attempt to get hold of the page size based on what we might have
|
||||||
|
been told at startup time in _dl_pagesize. This will be obsolete
|
||||||
|
when I finish the kernel hooks for a proper sysconf(), stay tuned.
|
||||||
|
|
||||||
|
Sparc 64 merge:
|
||||||
|
|
||||||
|
* sysdeps/sparc/sparc64/dl-machine.h (ELF_FIXUP_RETURN_VALUE): New.
|
||||||
|
Figure out the right thing to return based on the .plt format.
|
||||||
|
|
||||||
|
* sysdeps/sparc/sparc64/fpu/fpu_control.h: Update comment.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/sparc64/bits/types.h (__dev_t):
|
||||||
|
Should have been 64-bits wide.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h: sll->sllx,
|
||||||
|
optimize for branch delay slot usage.
|
||||||
|
|
||||||
|
1997-08-22 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||||
|
|
||||||
|
* csu/Makefile ($(objpfx)crt%.o): Fix a missing *.so -> *.os
|
||||||
|
change.
|
||||||
|
|
||||||
|
1997-08-20 Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||||
|
|
||||||
|
* math/libm-test.c (identities): Change epsilon.
|
||||||
|
|
||||||
|
* sysdeps/i386/fpu/bits/mathinline.h: Correct arguments to fabs,
|
||||||
|
fabsf, fabsl, __fabsl.
|
||||||
|
|
||||||
1997-08-20 05:30 Ulrich Drepper <drepper@cygnus.com>
|
1997-08-20 05:30 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
* catgets/catgets.c (catclose): Use __munmap instead of munmap.
|
* catgets/catgets.c (catclose): Use __munmap instead of munmap.
|
||||||
@ -120,10 +298,10 @@
|
|||||||
|
|
||||||
* sysdeps/libm-i387/e_remainder.S: Pretty print.
|
* sysdeps/libm-i387/e_remainder.S: Pretty print.
|
||||||
* sysdeps/libm-i387/e_remainderf.S: Likewise.
|
* sysdeps/libm-i387/e_remainderf.S: Likewise.
|
||||||
* sysdeps/libm-i387/e_remainderl.S: Pop extra value for FPU stack.
|
* sysdeps/libm-i387/e_remainderl.S: Pop extra value from FPU stack.
|
||||||
* sysdeps/libm-i387/s_cexp.S: Little optimization.
|
* sysdeps/libm-i387/s_cexp.S: Little optimization.
|
||||||
* sysdeps/libm-i387/s_cexpl.S: Likewise.
|
* sysdeps/libm-i387/s_cexpl.S: Likewise.
|
||||||
* sysdep/libm-ieee754/s_csinhl.c: Include <fenv.h>.
|
* sysdeps/libm-ieee754/s_csinhl.c: Include <fenv.h>.
|
||||||
|
|
||||||
1997-08-18 15:21 Ulrich Drepper <drepper@cygnus.com>
|
1997-08-18 15:21 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
51
FAQ
51
FAQ
@ -565,7 +565,7 @@ by
|
|||||||
|
|
||||||
in the above example specs file to make it work for other systems.
|
in the above example specs file to make it work for other systems.
|
||||||
|
|
||||||
Version 2.7.2.2 does and future versions of GCC will automatically
|
Version 2.7.2.3 does and future versions of GCC will automatically
|
||||||
provide the correct specs.
|
provide the correct specs.
|
||||||
|
|
||||||
|
|
||||||
@ -595,13 +595,9 @@ GROUP ( libc.so.6 ld-linux.so.2 libc.a )
|
|||||||
any other system I saw. This is a bug, isn't it?''
|
any other system I saw. This is a bug, isn't it?''
|
||||||
|
|
||||||
[A18] {UD} No, this is no bug. This version of the GNU libc already
|
[A18] {UD} No, this is no bug. This version of the GNU libc already
|
||||||
follows the to-be-released POSIX.1g standard. In this standard
|
follows the Single Unix specifications (and I think the POSIX.1g
|
||||||
the type `size_t' is used for all parameters which describe a size.
|
draft which adopted the solution). The type for parameter describing
|
||||||
So better change now.
|
a size is now `socklen_t', a new type.
|
||||||
|
|
||||||
This change is critical for system which have
|
|
||||||
sizeof (int) != sizeof (size_t)
|
|
||||||
like the Alpha.
|
|
||||||
|
|
||||||
|
|
||||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||||
@ -617,28 +613,9 @@ invalid. I.e., an emulated FPU is for the libc as good as a real one.
|
|||||||
[Q20] ``How can I compile gcc 2.7.2.1 from the gcc source code using
|
[Q20] ``How can I compile gcc 2.7.2.1 from the gcc source code using
|
||||||
glibc 2.x?
|
glibc 2.x?
|
||||||
|
|
||||||
[A20] {AJ} There's only support for glibc 2.0 in gcc 2.7.2.2 or later.
|
[A20] {AJ} There's only correct support for glibc 2.0.x in gcc 2.7.2.3
|
||||||
|
or later. You should get at least gcc 2.7.2.3. All previous versions
|
||||||
gcc 2.7.2.2 has also a nasty bug. It installs its own version of
|
had problems with glibc support.
|
||||||
assert.h into /usr/<machine>/include that is not compatible with
|
|
||||||
glibc. Please remove this file - otherwise you get lots of problems
|
|
||||||
with configure.
|
|
||||||
|
|
||||||
For 2.7.2.2 you should also use the following patch and configure for
|
|
||||||
e.g. i486-linux.
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
--- configure Tue Feb 11 15:57:17 1997
|
|
||||||
+++ configure Wed Feb 12 23:09:29 1997
|
|
||||||
@@ -1021,7 +1021,7 @@
|
|
||||||
gnu_ld=yes
|
|
||||||
# GNU libc version 2 does not supply these;
|
|
||||||
# we want them from GCC.
|
|
||||||
- extra_parts="crtbegin.o crtend.o"
|
|
||||||
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
|
||||||
;;
|
|
||||||
i[3456]86-go32-msdos | i[3456]86-*-go32)
|
|
||||||
cpu_type=i386
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||||
@ -698,13 +675,13 @@ very beginning and if it is not usable `configure' will bark.
|
|||||||
[Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
|
[Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
|
||||||
works great. But the glibc NIS+ doesn't seem to work.''
|
works great. But the glibc NIS+ doesn't seem to work.''
|
||||||
|
|
||||||
[A24] The glibc NIS+ implementation uses a /var/nis/NIS_COLD_START
|
[A24] The glibc NIS+ implementation uses a /var/nis/NIS_COLD_START
|
||||||
file for storing information about the NIS+ server and their
|
file for storing information about the NIS+ server and their public
|
||||||
public keys, because the nis.conf file do not contain all
|
keys, because the nis.conf file do not contain all necessary
|
||||||
necessary information. You have to copy a NIS_COLD_START file
|
information. You have to copy a NIS_COLD_START file from a Solaris
|
||||||
from a Solaris client (the NIS_COLD_START file is byte order
|
client (the NIS_COLD_START file is byte order independend) or generate
|
||||||
independend) or generate it new with nisinit from the nis-tools
|
it new with nisinit from the nis-tools (look at
|
||||||
(look at http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html).
|
http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html).
|
||||||
|
|
||||||
|
|
||||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||||
|
11
config.sub
vendored
11
config.sub
vendored
@ -155,6 +155,7 @@ case $basic_machine in
|
|||||||
| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
|
| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
|
||||||
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
|
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
|
||||||
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
|
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
|
||||||
|
| mipstx39 | mipstx39el \
|
||||||
| sparc | sparclet | sparclite | sparc64)
|
| sparc | sparclet | sparclite | sparc64)
|
||||||
basic_machine=$basic_machine-unknown
|
basic_machine=$basic_machine-unknown
|
||||||
;;
|
;;
|
||||||
@ -179,7 +180,9 @@ case $basic_machine in
|
|||||||
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
|
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
|
||||||
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
|
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
|
||||||
| sparc64-* | mips64-* | mipsel-* \
|
| sparc64-* | mips64-* | mipsel-* \
|
||||||
| mips64el-* | mips64orion-* | mips64orionel-* | f301-*)
|
| mips64el-* | mips64orion-* | mips64orionel-* \
|
||||||
|
| mipstx39-* | mipstx39el-* \
|
||||||
|
| f301-*)
|
||||||
;;
|
;;
|
||||||
# Recognize the various machine names and aliases which stand
|
# Recognize the various machine names and aliases which stand
|
||||||
# for a CPU type and a company and sometimes even an OS.
|
# for a CPU type and a company and sometimes even an OS.
|
||||||
@ -568,6 +571,12 @@ case $basic_machine in
|
|||||||
basic_machine=i386-sequent
|
basic_machine=i386-sequent
|
||||||
os=-dynix
|
os=-dynix
|
||||||
;;
|
;;
|
||||||
|
tx39)
|
||||||
|
basic_machine=mipstx39-unknown
|
||||||
|
;;
|
||||||
|
tx39el)
|
||||||
|
basic_machine=mipstx39el-unknown
|
||||||
|
;;
|
||||||
tower | tower-32)
|
tower | tower-32)
|
||||||
basic_machine=m68k-ncr
|
basic_machine=m68k-ncr
|
||||||
;;
|
;;
|
||||||
|
2
configure
vendored
2
configure
vendored
@ -1091,7 +1091,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
|
|||||||
|
|
||||||
if test "$INSTALL" = "${srcdir}/install-sh -c"; then
|
if test "$INSTALL" = "${srcdir}/install-sh -c"; then
|
||||||
# The makefiles need to use a different form to find it in $srcdir.
|
# The makefiles need to use a different form to find it in $srcdir.
|
||||||
INSTALL='$(..)./install-sh -c'
|
INSTALL='\$(..)./install-sh -c'
|
||||||
fi
|
fi
|
||||||
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
|
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
|
||||||
echo "configure:1098: checking whether ln -s works" >&5
|
echo "configure:1098: checking whether ln -s works" >&5
|
||||||
|
@ -371,7 +371,7 @@ AC_MSG_RESULT(sysdeps/generic sysdeps/stub)
|
|||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
if test "$INSTALL" = "${srcdir}/install-sh -c"; then
|
if test "$INSTALL" = "${srcdir}/install-sh -c"; then
|
||||||
# The makefiles need to use a different form to find it in $srcdir.
|
# The makefiles need to use a different form to find it in $srcdir.
|
||||||
INSTALL='$(..)./install-sh -c'
|
INSTALL='\$(..)./install-sh -c'
|
||||||
fi
|
fi
|
||||||
AC_PROG_LN_S
|
AC_PROG_LN_S
|
||||||
AC_CHECK_PROGS(MSGFMT, msgfmt gmsgfmt, :)
|
AC_CHECK_PROGS(MSGFMT, msgfmt gmsgfmt, :)
|
||||||
|
@ -59,10 +59,10 @@ omit-deps += $(crtstuff)
|
|||||||
|
|
||||||
# Special rules for the building of crti.o and crtn.o
|
# Special rules for the building of crti.o and crtn.o
|
||||||
$(objpfx)crt%.o: $(objpfx)crt%.S $(objpfx)defs.h
|
$(objpfx)crt%.o: $(objpfx)crt%.S $(objpfx)defs.h
|
||||||
$(compile.S) -g0 $(ASFLAGS-.so) -o $@
|
$(compile.S) -g0 $(ASFLAGS-.os) -o $@
|
||||||
|
|
||||||
$(objpfx)initfini.s: initfini.c
|
$(objpfx)initfini.s: initfini.c
|
||||||
$(compile.c) -g0 -S -fPIC -finhibit-size-directive \
|
$(compile.c) -O0 -g0 -S -fPIC -finhibit-size-directive \
|
||||||
$(no-exceptions) -o $@
|
$(no-exceptions) -o $@
|
||||||
|
|
||||||
# We only have one kind of startup code files. Static binaries and
|
# We only have one kind of startup code files. Static binaries and
|
||||||
|
235
elf/dl-deps.c
235
elf/dl-deps.c
@ -28,6 +28,10 @@
|
|||||||
is signaled by the AUXTAG entry in l_info. */
|
is signaled by the AUXTAG entry in l_info. */
|
||||||
#define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
|
#define AUXTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
|
||||||
+ DT_EXTRATAGIDX (DT_AUXILIARY))
|
+ DT_EXTRATAGIDX (DT_AUXILIARY))
|
||||||
|
/* Whether an shared object references one or more auxiliary objects
|
||||||
|
is signaled by the AUXTAG entry in l_info. */
|
||||||
|
#define FILTERTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGNUM \
|
||||||
|
+ DT_EXTRATAGIDX (DT_FILTER))
|
||||||
|
|
||||||
|
|
||||||
/* When loading auxiliary objects we must ignore errors. It's ok if
|
/* When loading auxiliary objects we must ignore errors. It's ok if
|
||||||
@ -138,7 +142,7 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
{
|
{
|
||||||
struct link_map *l = runp->map;
|
struct link_map *l = runp->map;
|
||||||
|
|
||||||
if (l->l_info[AUXTAG] || l->l_info[DT_NEEDED])
|
if (l->l_info[AUXTAG] || l->l_info[FILTERTAG] || l->l_info[DT_NEEDED])
|
||||||
{
|
{
|
||||||
const char *strtab = ((void *) l->l_addr
|
const char *strtab = ((void *) l->l_addr
|
||||||
+ l->l_info[DT_STRTAB]->d_un.d_ptr);
|
+ l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||||
@ -190,119 +194,87 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
dep->l_reserved = 1;
|
dep->l_reserved = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (d->d_tag == DT_AUXILIARY)
|
else if (d->d_tag == DT_AUXILIARY || d->d_tag == DT_FILTER)
|
||||||
{
|
{
|
||||||
char *errstring;
|
char *errstring;
|
||||||
const char *objname;
|
const char *objname;
|
||||||
|
struct list *newp;
|
||||||
|
|
||||||
/* Store the tag in the argument structure. */
|
if (d->d_tag == DT_AUXILIARY)
|
||||||
args.d = d;
|
|
||||||
|
|
||||||
if (_dl_catch_error (&errstring, &objname, openaux, &args))
|
|
||||||
{
|
{
|
||||||
/* We are not interested in the error message. */
|
/* Store the tag in the argument structure. */
|
||||||
assert (errstring != NULL);
|
args.d = d;
|
||||||
free (errstring);
|
|
||||||
|
/* We must be prepared that the addressed shared
|
||||||
|
object is not available. */
|
||||||
|
if (_dl_catch_error (&errstring, &objname, openaux, &args))
|
||||||
|
{
|
||||||
|
/* We are not interested in the error message. */
|
||||||
|
assert (errstring != NULL);
|
||||||
|
free (errstring);
|
||||||
|
|
||||||
|
/* Simply ignore this error and continue the work. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
/* For filter objects the dependency must be available. */
|
||||||
|
args.aux = _dl_map_object (l, strtab + d->d_un.d_val,
|
||||||
|
(l->l_type == lt_executable
|
||||||
|
? lt_library : l->l_type),
|
||||||
|
trace_mode);
|
||||||
|
|
||||||
|
/* The auxiliary object is actually available.
|
||||||
|
Incorporate the map in all the lists. */
|
||||||
|
|
||||||
|
/* Allocate new entry. This always has to be done. */
|
||||||
|
newp = alloca (sizeof (struct list));
|
||||||
|
|
||||||
|
/* Copy the content of the current entry over. */
|
||||||
|
memcpy (newp, orig, sizeof (*newp));
|
||||||
|
|
||||||
|
/* Initialize new entry. */
|
||||||
|
orig->done = 0;
|
||||||
|
orig->map = args.aux;
|
||||||
|
orig->dup = newp;
|
||||||
|
|
||||||
|
/* We must handle two situations here: the map is new,
|
||||||
|
so we must add it in all three lists. If the map
|
||||||
|
is already known, we have two further possibilities:
|
||||||
|
- if the object is before the current map in the
|
||||||
|
search list, we do nothing. It is already found
|
||||||
|
early
|
||||||
|
- if the object is after the current one, we must
|
||||||
|
move it just before the current map to make sure
|
||||||
|
the symbols are found early enough
|
||||||
|
*/
|
||||||
|
if (args.aux->l_reserved)
|
||||||
{
|
{
|
||||||
/* The auxiliary object is actually available.
|
/* The object is already somewhere in the list.
|
||||||
Incorporate the map in all the lists. */
|
Locate it first. */
|
||||||
|
struct list *late;
|
||||||
|
|
||||||
/* Allocate new entry. This always has to be done. */
|
/* This object is already in the search list we
|
||||||
struct list *newp = alloca (sizeof (struct list));
|
are building. Don't add a duplicate pointer.
|
||||||
|
Release the reference just added by
|
||||||
|
_dl_map_object. */
|
||||||
|
--args.aux->l_opencount;
|
||||||
|
|
||||||
/* Copy the content of the current entry over. */
|
for (late = orig; late->unique; late = late->unique)
|
||||||
memcpy (newp, orig, sizeof (*newp));
|
if (late->unique->map == args.aux)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Initialize new entry. */
|
if (late->unique)
|
||||||
orig->done = 0;
|
|
||||||
orig->map = args.aux;
|
|
||||||
orig->dup = newp;
|
|
||||||
|
|
||||||
/* We must handle two situations here: the map is new,
|
|
||||||
so we must add it in all three lists. If the map
|
|
||||||
is already known, we have two further possibilities:
|
|
||||||
- if the object is before the current map in the
|
|
||||||
search list, we do nothing. It is already found
|
|
||||||
early
|
|
||||||
- if the object is after the current one, we must
|
|
||||||
move it just before the current map to make sure
|
|
||||||
the symbols are found early enough
|
|
||||||
*/
|
|
||||||
if (args.aux->l_reserved)
|
|
||||||
{
|
{
|
||||||
/* The object is already somewhere in the
|
/* The object is somewhere behind the current
|
||||||
list. Locate it first. */
|
position in the search path. We have to
|
||||||
struct list *late;
|
move it to this earlier position. */
|
||||||
|
|
||||||
/* This object is already in the search list
|
|
||||||
we are building. Don't add a duplicate
|
|
||||||
pointer. Release the reference just added
|
|
||||||
by _dl_map_object. */
|
|
||||||
--args.aux->l_opencount;
|
|
||||||
|
|
||||||
for (late = orig; late->unique; late = late->unique)
|
|
||||||
if (late->unique->map == args.aux)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (late->unique)
|
|
||||||
{
|
|
||||||
/* The object is somewhere behind the current
|
|
||||||
position in the search path. We have to
|
|
||||||
move it to this earlier position. */
|
|
||||||
orig->unique = newp;
|
|
||||||
|
|
||||||
/* Now remove the later entry from the unique
|
|
||||||
list. */
|
|
||||||
late->unique = late->unique->unique;
|
|
||||||
|
|
||||||
/* We must move the earlier in the chain. */
|
|
||||||
if (args.aux->l_prev)
|
|
||||||
args.aux->l_prev->l_next = args.aux->l_next;
|
|
||||||
if (args.aux->l_next)
|
|
||||||
args.aux->l_next->l_prev = args.aux->l_prev;
|
|
||||||
|
|
||||||
args.aux->l_prev = newp->map->l_prev;
|
|
||||||
newp->map->l_prev = args.aux;
|
|
||||||
if (args.aux->l_prev != NULL)
|
|
||||||
args.aux->l_prev->l_next = args.aux;
|
|
||||||
args.aux->l_next = newp->map;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The object must be somewhere earlier in
|
|
||||||
the list. That's good, we only have to
|
|
||||||
insert an entry for the duplicate list. */
|
|
||||||
orig->unique = NULL; /* Never used. */
|
|
||||||
|
|
||||||
/* Now we have a problem. The element pointing
|
|
||||||
to ORIG in the unique list must point to
|
|
||||||
NEWP now. This is the only place where we
|
|
||||||
need this backreference and this situation
|
|
||||||
is really not that frequent. So we don't
|
|
||||||
use a double-linked list but instead search
|
|
||||||
for the preceding element. */
|
|
||||||
late = head;
|
|
||||||
while (late->unique != orig)
|
|
||||||
late = late->unique;
|
|
||||||
late->unique = newp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This is easy. We just add the symbol right
|
|
||||||
here. */
|
|
||||||
orig->unique = newp;
|
orig->unique = newp;
|
||||||
++nlist;
|
|
||||||
/* Set the mark bit that says it's already in
|
|
||||||
the list. */
|
|
||||||
args.aux->l_reserved = 1;
|
|
||||||
|
|
||||||
/* The only problem is that in the double linked
|
/* Now remove the later entry from the unique list. */
|
||||||
list of all objects we don't have this new
|
late->unique = late->unique->unique;
|
||||||
object at the correct place. Correct this
|
|
||||||
here. */
|
/* We must move the earlier in the chain. */
|
||||||
if (args.aux->l_prev)
|
if (args.aux->l_prev)
|
||||||
args.aux->l_prev->l_next = args.aux->l_next;
|
args.aux->l_prev->l_next = args.aux->l_next;
|
||||||
if (args.aux->l_next)
|
if (args.aux->l_next)
|
||||||
@ -314,19 +286,60 @@ _dl_map_object_deps (struct link_map *map,
|
|||||||
args.aux->l_prev->l_next = args.aux;
|
args.aux->l_prev->l_next = args.aux;
|
||||||
args.aux->l_next = newp->map;
|
args.aux->l_next = newp->map;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The object must be somewhere earlier in the
|
||||||
|
list. That's good, we only have to insert
|
||||||
|
an entry for the duplicate list. */
|
||||||
|
orig->unique = NULL; /* Never used. */
|
||||||
|
|
||||||
/* Move the tail pointers if necessary. */
|
/* Now we have a problem. The element
|
||||||
if (orig == utail)
|
pointing to ORIG in the unique list must
|
||||||
utail = newp;
|
point to NEWP now. This is the only place
|
||||||
if (orig == dtail)
|
where we need this backreference and this
|
||||||
dtail = newp;
|
situation is really not that frequent. So
|
||||||
|
we don't use a double-linked list but
|
||||||
/* Move on the insert point. */
|
instead search for the preceding element. */
|
||||||
orig = newp;
|
late = head;
|
||||||
|
while (late->unique != orig)
|
||||||
/* We always add an entry to the duplicate list. */
|
late = late->unique;
|
||||||
++nduplist;
|
late->unique = newp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is easy. We just add the symbol right here. */
|
||||||
|
orig->unique = newp;
|
||||||
|
++nlist;
|
||||||
|
/* Set the mark bit that says it's already in the list. */
|
||||||
|
args.aux->l_reserved = 1;
|
||||||
|
|
||||||
|
/* The only problem is that in the double linked
|
||||||
|
list of all objects we don't have this new
|
||||||
|
object at the correct place. Correct this here. */
|
||||||
|
if (args.aux->l_prev)
|
||||||
|
args.aux->l_prev->l_next = args.aux->l_next;
|
||||||
|
if (args.aux->l_next)
|
||||||
|
args.aux->l_next->l_prev = args.aux->l_prev;
|
||||||
|
|
||||||
|
args.aux->l_prev = newp->map->l_prev;
|
||||||
|
newp->map->l_prev = args.aux;
|
||||||
|
if (args.aux->l_prev != NULL)
|
||||||
|
args.aux->l_prev->l_next = args.aux;
|
||||||
|
args.aux->l_next = newp->map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the tail pointers if necessary. */
|
||||||
|
if (orig == utail)
|
||||||
|
utail = newp;
|
||||||
|
if (orig == dtail)
|
||||||
|
dtail = newp;
|
||||||
|
|
||||||
|
/* Move on the insert point. */
|
||||||
|
orig = newp;
|
||||||
|
|
||||||
|
/* We always add an entry to the duplicate list. */
|
||||||
|
++nduplist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -406,6 +406,9 @@ _dl_init_paths (void)
|
|||||||
{
|
{
|
||||||
fake_path_list = (struct r_search_path_elem **)
|
fake_path_list = (struct r_search_path_elem **)
|
||||||
malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
|
malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
|
||||||
|
if (fake_path_list == NULL)
|
||||||
|
_dl_signal_error (ENOMEM, NULL,
|
||||||
|
"cannot create cache for search path");
|
||||||
|
|
||||||
(void) fillin_rpath (local_strdup (llp), fake_path_list, ":;",
|
(void) fillin_rpath (local_strdup (llp), fake_path_list, ":;",
|
||||||
__libc_enable_secure ? trusted_dirs : NULL);
|
__libc_enable_secure ? trusted_dirs : NULL);
|
||||||
@ -901,23 +904,33 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
|
|||||||
|
|
||||||
/* Look for this name among those already loaded. */
|
/* Look for this name among those already loaded. */
|
||||||
for (l = _dl_loaded; l; l = l->l_next)
|
for (l = _dl_loaded; l; l = l->l_next)
|
||||||
if (l->l_opencount > 0 && _dl_name_match_p (name, l) ||
|
{
|
||||||
/* If the requested name matches the soname of a loaded object,
|
/* If the requested name matches the soname of a loaded object,
|
||||||
use that object. */
|
use that object. Elide this check for names that have not
|
||||||
(l->l_info[DT_SONAME] &&
|
yet been opened. */
|
||||||
! strcmp (name, (const char *) (l->l_addr +
|
if (l->l_opencount <= 0)
|
||||||
l->l_info[DT_STRTAB]->d_un.d_ptr +
|
continue;
|
||||||
l->l_info[DT_SONAME]->d_un.d_val))))
|
if (!_dl_name_match_p (name, l))
|
||||||
{
|
{
|
||||||
/* The object is already loaded.
|
const char *soname;
|
||||||
Just bump its reference count and return it. */
|
|
||||||
const char *soname = (const char *) (l->l_addr +
|
if (l->l_info[DT_SONAME] == NULL)
|
||||||
l->l_info[DT_STRTAB]->d_un.d_ptr +
|
continue;
|
||||||
l->l_info[DT_SONAME]->d_un.d_val);
|
|
||||||
add_name_to_object (l, local_strdup (soname));
|
soname = (const char *) (l->l_addr
|
||||||
++l->l_opencount;
|
+ l->l_info[DT_STRTAB]->d_un.d_ptr
|
||||||
return l;
|
+ l->l_info[DT_SONAME]->d_un.d_val);
|
||||||
}
|
if (strcmp (name, soname) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* We have a match on a new name -- cache it. */
|
||||||
|
add_name_to_object (l, local_strdup (soname));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have a match -- bump the reference count and return it. */
|
||||||
|
++l->l_opencount;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
if (strchr (name, '/') == NULL)
|
if (strchr (name, '/') == NULL)
|
||||||
{
|
{
|
||||||
|
@ -93,6 +93,10 @@ do_lookup (const char *undef_name, unsigned long int hash,
|
|||||||
map->l_type == lt_executable)
|
map->l_type == lt_executable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* Skip objects without symbol tables. */
|
||||||
|
if (map->l_info[DT_SYMTAB] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||||
strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
|
strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||||
if (map->l_nversions > 0 && map->l_info[VERSTAG (DT_VERSYM)] != NULL)
|
if (map->l_nversions > 0 && map->l_info[VERSTAG (DT_VERSYM)] != NULL)
|
||||||
@ -364,8 +368,13 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
|
|||||||
void
|
void
|
||||||
_dl_setup_hash (struct link_map *map)
|
_dl_setup_hash (struct link_map *map)
|
||||||
{
|
{
|
||||||
ElfW(Symndx) *hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
|
ElfW(Symndx) *hash;
|
||||||
ElfW(Symndx) nchain;
|
ElfW(Symndx) nchain;
|
||||||
|
|
||||||
|
if (!map->l_info[DT_HASH])
|
||||||
|
return;
|
||||||
|
hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
|
||||||
|
|
||||||
map->l_nbuckets = *hash++;
|
map->l_nbuckets = *hash++;
|
||||||
nchain = *hash++;
|
nchain = *hash++;
|
||||||
map->l_buckets = hash;
|
map->l_buckets = hash;
|
||||||
|
@ -87,6 +87,10 @@ _dl_object_relocation_scope (struct link_map *l)
|
|||||||
# define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
|
# define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ELF_FIXUP_RETURN_VALUE
|
||||||
|
#define ELF_FIXUP_RETURN_VALUE(map, result) (result)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We need to define the function as a local symbol so that the reference
|
/* We need to define the function as a local symbol so that the reference
|
||||||
in the trampoline code will be a local PC-relative call. Tell the
|
in the trampoline code will be a local PC-relative call. Tell the
|
||||||
compiler not to worry that the function appears not to be called. */
|
compiler not to worry that the function appears not to be called. */
|
||||||
@ -120,6 +124,7 @@ fixup (
|
|||||||
const PLTREL *const reloc
|
const PLTREL *const reloc
|
||||||
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
|
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
|
||||||
reloc_offset);
|
reloc_offset);
|
||||||
|
ElfW(Addr) *const rel_addr = (ElfW(Addr) *)(l->l_addr + reloc->r_offset);
|
||||||
|
|
||||||
/* Set up the scope to find symbols referenced by this object. */
|
/* Set up the scope to find symbols referenced by this object. */
|
||||||
struct link_map **scope = _dl_object_relocation_scope (l);
|
struct link_map **scope = _dl_object_relocation_scope (l);
|
||||||
@ -144,21 +149,17 @@ fixup (
|
|||||||
|
|
||||||
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
|
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
|
||||||
&l->l_versions[ndx],
|
&l->l_versions[ndx],
|
||||||
(void *) (l->l_addr + reloc->r_offset));
|
(void *) rel_addr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
|
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
|
||||||
NULL, (void *) (l->l_addr + reloc->r_offset));
|
NULL, (void *) rel_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
*_dl_global_scope_end = NULL;
|
*_dl_global_scope_end = NULL;
|
||||||
|
|
||||||
/* Return the address that was written by the relocation. */
|
/* Return the address that was written by the relocation. */
|
||||||
#ifdef ELF_FIXUP_RETURNS_ADDRESS
|
return ELF_FIXUP_RETURN_VALUE(l, *rel_addr);
|
||||||
return (ElfW(Addr))(l->l_addr + reloc->r_offset);
|
|
||||||
#else
|
|
||||||
return *(ElfW(Addr) *) (l->l_addr + reloc->r_offset);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -219,17 +220,10 @@ profile_fixup (
|
|||||||
}
|
}
|
||||||
|
|
||||||
*_dl_global_scope_end = NULL;
|
*_dl_global_scope_end = NULL;
|
||||||
|
(*mcount_fct) (retaddr, result);
|
||||||
|
|
||||||
/* Return the address that was written by the relocation. */
|
/* Return the address that was written by the relocation. */
|
||||||
#ifdef ELF_FIXUP_RETURNS_ADDRESS
|
return ELF_FIXUP_RETURN_VALUE(l, result);
|
||||||
(*mcount_fct) (retaddr, result);
|
|
||||||
|
|
||||||
return &result; /* XXX This cannot work. What to do??? --drepper */
|
|
||||||
#else
|
|
||||||
(*mcount_fct) (retaddr, result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -155,16 +155,23 @@ int
|
|||||||
_dl_check_map_versions (struct link_map *map, int verbose)
|
_dl_check_map_versions (struct link_map *map, int verbose)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
const char *strtab = (const char *) (map->l_addr
|
const char *strtab;
|
||||||
+ map->l_info[DT_STRTAB]->d_un.d_ptr);
|
|
||||||
/* Pointer to section with needed versions. */
|
/* Pointer to section with needed versions. */
|
||||||
ElfW(Dyn) *dyn = map->l_info[VERSTAG (DT_VERNEED)];
|
ElfW(Dyn) *dyn;
|
||||||
/* Pointer to dynamic section with definitions. */
|
/* Pointer to dynamic section with definitions. */
|
||||||
ElfW(Dyn) *def = map->l_info[VERSTAG (DT_VERDEF)];
|
ElfW(Dyn) *def;
|
||||||
/* We need to find out which is the highest version index used
|
/* We need to find out which is the highest version index used
|
||||||
in a dependecy. */
|
in a dependecy. */
|
||||||
unsigned int ndx_high = 0;
|
unsigned int ndx_high = 0;
|
||||||
|
|
||||||
|
/* If we don't have a string table, we must be ok. */
|
||||||
|
if (map->l_info[DT_STRTAB] == NULL)
|
||||||
|
return 0;
|
||||||
|
strtab = (const char *) (map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||||
|
|
||||||
|
dyn = map->l_info[VERSTAG (DT_VERNEED)];
|
||||||
|
def = map->l_info[VERSTAG (DT_VERDEF)];
|
||||||
|
|
||||||
if (dyn != NULL)
|
if (dyn != NULL)
|
||||||
{
|
{
|
||||||
/* This file requires special versions from its dependencies. */
|
/* This file requires special versions from its dependencies. */
|
||||||
|
@ -783,6 +783,13 @@ typedef struct
|
|||||||
#define DT_SPARC_PLTFMT 0x70000001 /* .plt format version/type */
|
#define DT_SPARC_PLTFMT 0x70000001 /* .plt format version/type */
|
||||||
#define DT_SPARC_NUM 2
|
#define DT_SPARC_NUM 2
|
||||||
|
|
||||||
|
/* Bits present in AT_HWCAP, primarily for Sparc32. */
|
||||||
|
|
||||||
|
#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */
|
||||||
|
#define HWCAP_SPARC_STBAR 2
|
||||||
|
#define HWCAP_SPARC_SWAP 4
|
||||||
|
#define HWCAP_SPARC_MULDIV 8
|
||||||
|
|
||||||
/* MIPS R3000 specific definitions. */
|
/* MIPS R3000 specific definitions. */
|
||||||
|
|
||||||
/* Legal values for e_flags field of Elf32_Ehdr. */
|
/* Legal values for e_flags field of Elf32_Ehdr. */
|
||||||
|
133
elf/rtld.c
133
elf/rtld.c
@ -53,13 +53,13 @@ static void print_unresolved (int errcode, const char *objname,
|
|||||||
static void print_missing_version (int errcode, const char *objname,
|
static void print_missing_version (int errcode, const char *objname,
|
||||||
const char *errsting);
|
const char *errsting);
|
||||||
|
|
||||||
|
|
||||||
int _dl_argc;
|
int _dl_argc;
|
||||||
char **_dl_argv;
|
char **_dl_argv;
|
||||||
const char *_dl_rpath;
|
const char *_dl_rpath;
|
||||||
int _dl_verbose;
|
int _dl_verbose;
|
||||||
const char *_dl_platform;
|
const char *_dl_platform;
|
||||||
size_t _dl_platformlen;
|
size_t _dl_platformlen;
|
||||||
|
unsigned long _dl_hwcap;
|
||||||
struct r_search_path *_dl_search_paths;
|
struct r_search_path *_dl_search_paths;
|
||||||
const char *_dl_profile;
|
const char *_dl_profile;
|
||||||
const char *_dl_profile_output;
|
const char *_dl_profile_output;
|
||||||
@ -80,6 +80,7 @@ static void dl_main (const ElfW(Phdr) *phdr,
|
|||||||
|
|
||||||
struct link_map _dl_rtld_map;
|
struct link_map _dl_rtld_map;
|
||||||
struct libname_list _dl_rtld_libname;
|
struct libname_list _dl_rtld_libname;
|
||||||
|
struct libname_list _dl_rtld_libname2;
|
||||||
|
|
||||||
#ifdef RTLD_START
|
#ifdef RTLD_START
|
||||||
RTLD_START
|
RTLD_START
|
||||||
@ -119,19 +120,22 @@ _dl_start (void *arg)
|
|||||||
the operating system's program loader where to find the program
|
the operating system's program loader where to find the program
|
||||||
header table in core. */
|
header table in core. */
|
||||||
|
|
||||||
|
|
||||||
/* Transfer data about ourselves to the permanent link_map structure. */
|
/* Transfer data about ourselves to the permanent link_map structure. */
|
||||||
_dl_rtld_map.l_addr = bootstrap_map.l_addr;
|
_dl_rtld_map.l_addr = bootstrap_map.l_addr;
|
||||||
_dl_rtld_map.l_ld = bootstrap_map.l_ld;
|
_dl_rtld_map.l_ld = bootstrap_map.l_ld;
|
||||||
|
_dl_rtld_map.l_opencount = 1;
|
||||||
memcpy (_dl_rtld_map.l_info, bootstrap_map.l_info,
|
memcpy (_dl_rtld_map.l_info, bootstrap_map.l_info,
|
||||||
sizeof _dl_rtld_map.l_info);
|
sizeof _dl_rtld_map.l_info);
|
||||||
_dl_setup_hash (&_dl_rtld_map);
|
_dl_setup_hash (&_dl_rtld_map);
|
||||||
|
|
||||||
/* Cache the DT_RPATH stored in ld.so itself; this will be
|
/* Cache the DT_RPATH stored in ld.so itself; this will be
|
||||||
the default search path. */
|
the default search path. */
|
||||||
_dl_rpath = (void *) (_dl_rtld_map.l_addr +
|
if (_dl_rtld_map.l_info[DT_STRTAB] && _dl_rtld_map.l_info[DT_RPATH])
|
||||||
_dl_rtld_map.l_info[DT_STRTAB]->d_un.d_ptr +
|
{
|
||||||
_dl_rtld_map.l_info[DT_RPATH]->d_un.d_val);
|
_dl_rpath = (void *) (_dl_rtld_map.l_addr +
|
||||||
|
_dl_rtld_map.l_info[DT_STRTAB]->d_un.d_ptr +
|
||||||
|
_dl_rtld_map.l_info[DT_RPATH]->d_un.d_val);
|
||||||
|
}
|
||||||
|
|
||||||
/* Call the OS-dependent function to set up life so we can do things like
|
/* Call the OS-dependent function to set up life so we can do things like
|
||||||
file access. It will call `dl_main' (below) to do all the real work
|
file access. It will call `dl_main' (below) to do all the real work
|
||||||
@ -416,6 +420,23 @@ of this helper program; chances are you did not intend to run this program.\n",
|
|||||||
_dl_rtld_libname.name = (const char *) main_map->l_addr + ph->p_vaddr;
|
_dl_rtld_libname.name = (const char *) main_map->l_addr + ph->p_vaddr;
|
||||||
_dl_rtld_libname.next = NULL;
|
_dl_rtld_libname.next = NULL;
|
||||||
_dl_rtld_map.l_libname = &_dl_rtld_libname;
|
_dl_rtld_map.l_libname = &_dl_rtld_libname;
|
||||||
|
|
||||||
|
/* Ordinarilly, we would get additional names for the loader from
|
||||||
|
our DT_SONAME. This can't happen if we were actually linked as
|
||||||
|
a static executable (detect this case when we have no DYNAMIC).
|
||||||
|
If so, assume the filename component of the interpreter path to
|
||||||
|
be our SONAME, and add it to our name list. */
|
||||||
|
if (_dl_rtld_map.l_ld == NULL)
|
||||||
|
{
|
||||||
|
char *p = strrchr (_dl_rtld_libname.name, '/');
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
_dl_rtld_libname2.name = p+1;
|
||||||
|
_dl_rtld_libname2.next = NULL;
|
||||||
|
_dl_rtld_libname.next = &_dl_rtld_libname2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
has_interp = 1;
|
has_interp = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -696,74 +717,70 @@ of this helper program; chances are you did not intend to run this program.\n",
|
|||||||
|
|
||||||
for (map = _dl_loaded; map != NULL; map = map->l_next)
|
for (map = _dl_loaded; map != NULL; map = map->l_next)
|
||||||
{
|
{
|
||||||
const char *strtab =
|
const char *strtab;
|
||||||
(const char *) (map->l_addr
|
|
||||||
+ map->l_info[DT_STRTAB]->d_un.d_ptr);
|
|
||||||
ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
|
ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
|
||||||
|
ElfW(Verneed) *ent;
|
||||||
|
|
||||||
if (dyn != NULL)
|
if (dyn == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
strtab = (const char *)
|
||||||
|
(map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||||
|
ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
|
||||||
|
|
||||||
|
if (first)
|
||||||
{
|
{
|
||||||
ElfW(Verneed) *ent =
|
_dl_sysdep_message ("\n\tVersion information:\n", NULL);
|
||||||
(ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
|
first = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (first)
|
_dl_sysdep_message ("\t", (map->l_name[0]
|
||||||
{
|
? map->l_name : _dl_argv[0]),
|
||||||
_dl_sysdep_message ("\n\tVersion information:\n",
|
":\n", NULL);
|
||||||
NULL);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dl_sysdep_message ("\t", (map->l_name[0]
|
while (1)
|
||||||
? map->l_name
|
{
|
||||||
: _dl_argv[0]), ":\n",
|
ElfW(Vernaux) *aux;
|
||||||
NULL);
|
struct link_map *needed;
|
||||||
|
|
||||||
|
needed = find_needed (strtab + ent->vn_file);
|
||||||
|
aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
ElfW(Vernaux) *aux;
|
const char *fname = NULL;
|
||||||
struct link_map *needed;
|
|
||||||
|
|
||||||
needed = find_needed (strtab + ent->vn_file);
|
_dl_sysdep_message ("\t\t",
|
||||||
aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
|
strtab + ent->vn_file,
|
||||||
|
" (", strtab + aux->vna_name,
|
||||||
|
") ",
|
||||||
|
(aux->vna_flags
|
||||||
|
& VER_FLG_WEAK
|
||||||
|
? "[WEAK] " : ""),
|
||||||
|
"=> ", NULL);
|
||||||
|
|
||||||
while (1)
|
if (needed != NULL
|
||||||
{
|
&& match_version (strtab+aux->vna_name, needed))
|
||||||
const char *fname = NULL;
|
fname = needed->l_name;
|
||||||
|
|
||||||
_dl_sysdep_message ("\t\t",
|
_dl_sysdep_message (fname ?: "not found", "\n",
|
||||||
strtab + ent->vn_file,
|
NULL);
|
||||||
" (", strtab + aux->vna_name,
|
|
||||||
") ",
|
|
||||||
(aux->vna_flags
|
|
||||||
& VER_FLG_WEAK
|
|
||||||
? "[WEAK] " : ""),
|
|
||||||
"=> ", NULL);
|
|
||||||
|
|
||||||
if (needed != NULL
|
if (aux->vna_next == 0)
|
||||||
&& match_version (strtab + aux->vna_name,
|
/* No more symbols. */
|
||||||
needed))
|
|
||||||
fname = needed->l_name;
|
|
||||||
|
|
||||||
_dl_sysdep_message (fname ?: "not found", "\n",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (aux->vna_next == 0)
|
|
||||||
/* No more symbols. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Next symbol. */
|
|
||||||
aux = (ElfW(Vernaux) *) ((char *) aux
|
|
||||||
+ aux->vna_next);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ent->vn_next == 0)
|
|
||||||
/* No more dependencies. */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Next dependency. */
|
/* Next symbol. */
|
||||||
ent = (ElfW(Verneed) *) ((char *) ent
|
aux = (ElfW(Vernaux) *) ((char *) aux
|
||||||
+ ent->vn_next);
|
+ aux->vna_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ent->vn_next == 0)
|
||||||
|
/* No more dependencies. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Next dependency. */
|
||||||
|
ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,9 +99,9 @@ _nl_find_domain (dirname, locale, domainname)
|
|||||||
|
|
||||||
language[_territory][+audience][+special][,[sponsor][_revision]]
|
language[_territory][+audience][+special][,[sponsor][_revision]]
|
||||||
|
|
||||||
Beside the first all of them are allowed to be missing. If the
|
Beside the first part all of them are allowed to be missing. If
|
||||||
full specified locale is not found, the less specific one are
|
the full specified locale is not found, the less specific one are
|
||||||
looked for. The various part will be stripped of according to
|
looked for. The various parts will be stripped off according to
|
||||||
the following order:
|
the following order:
|
||||||
(1) revision
|
(1) revision
|
||||||
(2) sponsor
|
(2) sponsor
|
||||||
|
@ -85,7 +85,7 @@ void free ();
|
|||||||
# define strdup __strdup
|
# define strdup __strdup
|
||||||
|
|
||||||
/* We need locking here since we can be called from different palces. */
|
/* We need locking here since we can be called from different palces. */
|
||||||
# include <libc-lock.h>
|
# include <bits/libc-lock.h>
|
||||||
|
|
||||||
__libc_lock_define_initialized (static, lock);
|
__libc_lock_define_initialized (static, lock);
|
||||||
#endif
|
#endif
|
||||||
|
2
libc.map
2
libc.map
@ -41,7 +41,7 @@ GLIBC_2.0 {
|
|||||||
# functions with required interface outside normal name space
|
# functions with required interface outside normal name space
|
||||||
_exit; __ivaliduser; __open_catalog;
|
_exit; __ivaliduser; __open_catalog;
|
||||||
__argz_count; __argz_stringify; __argz_next;
|
__argz_count; __argz_stringify; __argz_next;
|
||||||
__check_rhosts_file; __rcmd_errstr;
|
__check_rhosts_file; __rcmd_errstr; __xpg_basename;
|
||||||
|
|
||||||
# functions from the experimental locale implementation
|
# functions from the experimental locale implementation
|
||||||
__*_l; __newlocale; __duplocale; __freelocale;
|
__*_l; __newlocale; __duplocale; __freelocale;
|
||||||
|
@ -51,6 +51,12 @@ typedef struct _IO_FILE FILE;
|
|||||||
|
|
||||||
#include <libio.h>
|
#include <libio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# define __STDIO_INLINE __inline
|
||||||
|
#else
|
||||||
|
# define __STDIO_INLINE extern __inline
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The type of the second argument to `fgetpos' and `fsetpos'. */
|
/* The type of the second argument to `fgetpos' and `fsetpos'. */
|
||||||
typedef _G_fpos_t fpos_t;
|
typedef _G_fpos_t fpos_t;
|
||||||
|
|
||||||
@ -235,36 +241,40 @@ extern int vsprintf __P ((char *__restrict __s,
|
|||||||
_G_va_list __arg));
|
_G_va_list __arg));
|
||||||
|
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
vprintf (const char *__restrict __fmt, _G_va_list __arg)
|
vprintf (const char *__restrict __fmt, _G_va_list __arg)
|
||||||
{
|
{
|
||||||
return vfprintf (stdout, __fmt, __arg);
|
return vfprintf (stdout, __fmt, __arg);
|
||||||
}
|
}
|
||||||
#endif /* Optimizing. */
|
#endif /* Optimizing. */
|
||||||
|
|
||||||
#if defined __USE_GNU || defined __USE_ISOC9X
|
#if defined __USE_BSD || defined __USE_ISOC9X
|
||||||
/* Maximum chars of output to write in MAXLEN. */
|
/* Maximum chars of output to write in MAXLEN. */
|
||||||
extern int __snprintf __P ((char *__s, size_t __maxlen,
|
extern int __snprintf __P ((char *__restrict __s, size_t __maxlen,
|
||||||
__const char *__format, ...));
|
__const char *__restrict __format, ...));
|
||||||
extern int snprintf __P ((char *__s, size_t __maxlen,
|
extern int snprintf __P ((char *__restrict __s, size_t __maxlen,
|
||||||
__const char *__format, ...));
|
__const char *__restrict __format, ...));
|
||||||
|
|
||||||
extern int __vsnprintf __P ((char *__s, size_t __maxlen,
|
extern int __vsnprintf __P ((char *__restrict __s, size_t __maxlen,
|
||||||
__const char *__format, _G_va_list __arg));
|
__const char *__restrict __format,
|
||||||
extern int vsnprintf __P ((char *__s, size_t __maxlen,
|
_G_va_list __arg));
|
||||||
__const char *__format, _G_va_list __arg));
|
extern int vsnprintf __P ((char *__restrict __s, size_t __maxlen,
|
||||||
|
__const char *__restrict __format,
|
||||||
|
_G_va_list __arg));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __USE_GNU
|
#ifdef __USE_GNU
|
||||||
/* Write formatted output to a string dynamically allocated with `malloc'.
|
/* Write formatted output to a string dynamically allocated with `malloc'.
|
||||||
Store the address of the string in *PTR. */
|
Store the address of the string in *PTR. */
|
||||||
extern int vasprintf __P ((char **__ptr, __const char *__f,
|
extern int vasprintf __P ((char **__restrict __ptr,
|
||||||
_G_va_list __arg));
|
__const char *__restrict __f, _G_va_list __arg));
|
||||||
extern int asprintf __P ((char **__ptr, __const char *__fmt, ...));
|
extern int asprintf __P ((char **__restrict __ptr,
|
||||||
|
__const char *__restrict __fmt, ...));
|
||||||
|
|
||||||
/* Write formatted output to a file descriptor. */
|
/* Write formatted output to a file descriptor. */
|
||||||
extern int vdprintf __P ((int __fd, __const char *__fmt, _G_va_list __arg));
|
extern int vdprintf __P ((int __fd, __const char *__restrict __fmt,
|
||||||
extern int dprintf __P ((int __fd, __const char *__fmt, ...));
|
_G_va_list __arg));
|
||||||
|
extern int dprintf __P ((int __fd, __const char *__restrict __fmt, ...));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -279,19 +289,24 @@ extern int sscanf __P ((__const char *__restrict __s,
|
|||||||
|
|
||||||
#ifdef __USE_GNU
|
#ifdef __USE_GNU
|
||||||
/* Read formatted input from S into argument list ARG. */
|
/* Read formatted input from S into argument list ARG. */
|
||||||
extern int __vfscanf __P ((FILE *__s, __const char *__format,
|
extern int __vfscanf __P ((FILE *__restrict __s,
|
||||||
|
__const char *__restrict __format,
|
||||||
_G_va_list __arg));
|
_G_va_list __arg));
|
||||||
extern int vfscanf __P ((FILE *__s, __const char *__format,
|
extern int vfscanf __P ((FILE *__restrict __s,
|
||||||
|
__const char *__restrict __format,
|
||||||
_G_va_list __arg));
|
_G_va_list __arg));
|
||||||
|
|
||||||
/* Read formatted input from stdin into argument list ARG. */
|
/* Read formatted input from stdin into argument list ARG. */
|
||||||
extern int __vscanf __P ((__const char *__format, _G_va_list __arg));
|
extern int __vscanf __P ((__const char *__restrict __format,
|
||||||
extern int vscanf __P ((__const char *__format, _G_va_list __arg));
|
_G_va_list __arg));
|
||||||
|
extern int vscanf __P ((__const char *__restrict __format, _G_va_list __arg));
|
||||||
|
|
||||||
/* Read formatted input from S into argument list ARG. */
|
/* Read formatted input from S into argument list ARG. */
|
||||||
extern int __vsscanf __P ((__const char *__s, __const char *__format,
|
extern int __vsscanf __P ((__const char *__restrict __s,
|
||||||
|
__const char *__restrict __format,
|
||||||
_G_va_list __arg));
|
_G_va_list __arg));
|
||||||
extern int vsscanf __P ((__const char *__s, __const char *__format,
|
extern int vsscanf __P ((__const char *__restrict __s,
|
||||||
|
__const char *__restrict __format,
|
||||||
_G_va_list __arg));
|
_G_va_list __arg));
|
||||||
#endif /* Use GNU. */
|
#endif /* Use GNU. */
|
||||||
|
|
||||||
@ -308,7 +323,7 @@ extern int getchar __P ((void));
|
|||||||
#define getc(_fp) _IO_getc (_fp)
|
#define getc(_fp) _IO_getc (_fp)
|
||||||
|
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
getchar (void)
|
getchar (void)
|
||||||
{
|
{
|
||||||
return _IO_getc (stdin);
|
return _IO_getc (stdin);
|
||||||
@ -321,13 +336,13 @@ extern int getc_unlocked __P ((FILE *__stream));
|
|||||||
extern int getchar_unlocked __P ((void));
|
extern int getchar_unlocked __P ((void));
|
||||||
|
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
getc_unlocked (FILE *__fp)
|
getc_unlocked (FILE *__fp)
|
||||||
{
|
{
|
||||||
return _IO_getc_unlocked (__fp);
|
return _IO_getc_unlocked (__fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
getchar_unlocked (void)
|
getchar_unlocked (void)
|
||||||
{
|
{
|
||||||
return _IO_getc_unlocked (stdin);
|
return _IO_getc_unlocked (stdin);
|
||||||
@ -348,7 +363,7 @@ extern int putchar __P ((int __c));
|
|||||||
#define putc(_ch, _fp) _IO_putc (_ch, _fp)
|
#define putc(_ch, _fp) _IO_putc (_ch, _fp)
|
||||||
|
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
putchar (int __c)
|
putchar (int __c)
|
||||||
{
|
{
|
||||||
return _IO_putc (__c, stdout);
|
return _IO_putc (__c, stdout);
|
||||||
@ -360,7 +375,7 @@ putchar (int __c)
|
|||||||
extern int fputc_unlocked __P ((int __c, FILE *__stream));
|
extern int fputc_unlocked __P ((int __c, FILE *__stream));
|
||||||
|
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
fputc_unlocked (int __c, FILE *__stream)
|
fputc_unlocked (int __c, FILE *__stream)
|
||||||
{
|
{
|
||||||
return _IO_putc_unlocked (__c, __stream);
|
return _IO_putc_unlocked (__c, __stream);
|
||||||
@ -374,13 +389,13 @@ extern int putc_unlocked __P ((int __c, FILE *__stream));
|
|||||||
extern int putchar_unlocked __P ((int __c));
|
extern int putchar_unlocked __P ((int __c));
|
||||||
|
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
putc_unlocked (int __c, FILE *__stream)
|
putc_unlocked (int __c, FILE *__stream)
|
||||||
{
|
{
|
||||||
return _IO_putc_unlocked (__c, __stream);
|
return _IO_putc_unlocked (__c, __stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
putchar_unlocked (int __c)
|
putchar_unlocked (int __c)
|
||||||
{
|
{
|
||||||
return _IO_putc_unlocked (__c, stdout);
|
return _IO_putc_unlocked (__c, stdout);
|
||||||
@ -423,7 +438,7 @@ _IO_ssize_t __getline __P ((char **__lineptr, size_t *__n, FILE *__stream));
|
|||||||
_IO_ssize_t getline __P ((char **__lineptr, size_t *__n, FILE *__stream));
|
_IO_ssize_t getline __P ((char **__lineptr, size_t *__n, FILE *__stream));
|
||||||
|
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
extern __inline _IO_ssize_t
|
__STDIO_INLINE _IO_ssize_t
|
||||||
getline (char **__lineptr, size_t *__n, FILE *__stream)
|
getline (char **__lineptr, size_t *__n, FILE *__stream)
|
||||||
{
|
{
|
||||||
return __getdelim (__lineptr, __n, '\n', __stream);
|
return __getdelim (__lineptr, __n, '\n', __stream);
|
||||||
@ -488,13 +503,13 @@ extern int feof_unlocked __P ((FILE *__stream));
|
|||||||
extern int ferror_unlocked __P ((FILE *__stream));
|
extern int ferror_unlocked __P ((FILE *__stream));
|
||||||
|
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
feof_unlocked (FILE *__stream)
|
feof_unlocked (FILE *__stream)
|
||||||
{
|
{
|
||||||
return _IO_feof_unlocked (__stream);
|
return _IO_feof_unlocked (__stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline int
|
__STDIO_INLINE int
|
||||||
ferror_unlocked (FILE *__stream)
|
ferror_unlocked (FILE *__stream)
|
||||||
{
|
{
|
||||||
return _IO_ferror_unlocked (__stream);
|
return _IO_ferror_unlocked (__stream);
|
||||||
@ -579,6 +594,9 @@ extern void funlockfile __P ((FILE *__stream));
|
|||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
/* Define helper macro. */
|
||||||
|
#undef __STDIO_INLINE
|
||||||
|
|
||||||
#endif /* <stdio.h> included. */
|
#endif /* <stdio.h> included. */
|
||||||
|
|
||||||
#endif /* !_STDIO_H */
|
#endif /* !_STDIO_H */
|
||||||
|
@ -1,171 +1,190 @@
|
|||||||
/*
|
/*
|
||||||
* Defines the valid international currency symbols according to ISO-4217.
|
* Defines the valid international currency symbols according to ISO 4217.
|
||||||
* This is used in monetary.c(monetary_check).
|
* This is used in monetary.c(monetary_check).
|
||||||
*
|
*
|
||||||
* If you find something missing or wrong contact <bug-glibc@prep.ai.mit.edu>
|
* If you find something missing or wrong contact <bug-glibc@prep.ai.mit.edu>
|
||||||
*
|
*
|
||||||
* !!! The list has to be sorted !!!
|
* !!! The list has to be sorted !!!
|
||||||
*/
|
*/
|
||||||
DEFINE_INT_CURR("AED ") /* United Arab Emirates */
|
DEFINE_INT_CURR("ADP ") /* Andorran Peseta */
|
||||||
DEFINE_INT_CURR("AFA ") /* Afghanistan */
|
DEFINE_INT_CURR("AED ") /* United Arab Emirates Dirham */
|
||||||
DEFINE_INT_CURR("ALL ") /* Albania */
|
DEFINE_INT_CURR("AFA ") /* Afghanistan Afgani */
|
||||||
|
DEFINE_INT_CURR("ALL ") /* Albanian Lek */
|
||||||
|
DEFINE_INT_CURR("AMD ") /* Armenia Dram */
|
||||||
DEFINE_INT_CURR("ANG ") /* Netherlands Antilles */
|
DEFINE_INT_CURR("ANG ") /* Netherlands Antilles */
|
||||||
DEFINE_INT_CURR("AOK ") /* Angola */
|
DEFINE_INT_CURR("AOK ") /* Angolan Kwanza */
|
||||||
DEFINE_INT_CURR("ARP ") /* Argentina */
|
DEFINE_INT_CURR("AON ") /* Angolan New Kwanza */
|
||||||
DEFINE_INT_CURR("ATS ") /* Austria */
|
DEFINE_INT_CURR("ARP ") /* Argentine Peso */
|
||||||
DEFINE_INT_CURR("AUD ") /* Australia */
|
DEFINE_INT_CURR("ATS ") /* Austrian Schilling */
|
||||||
DEFINE_INT_CURR("BBD ") /* Barbados */
|
DEFINE_INT_CURR("AUD ") /* Australian Dollar */
|
||||||
DEFINE_INT_CURR("BDT ") /* Bangladesh */
|
DEFINE_INT_CURR("AZM ") /* Azerbaijan Manat */
|
||||||
DEFINE_INT_CURR("BEF ") /* Belgium */
|
DEFINE_INT_CURR("BBD ") /* Barbados Dollar */
|
||||||
DEFINE_INT_CURR("BGL ") /* Bulgaria */
|
DEFINE_INT_CURR("BDT ") /* Bangladesh Taka */
|
||||||
DEFINE_INT_CURR("BHD ") /* Bahrain */
|
DEFINE_INT_CURR("BEF ") /* Belgian Franc */
|
||||||
|
DEFINE_INT_CURR("BGL ") /* Bulgarian Lev */
|
||||||
|
DEFINE_INT_CURR("BHD ") /* Bahraini Dinar */
|
||||||
DEFINE_INT_CURR("BIF ") /* Burundi */
|
DEFINE_INT_CURR("BIF ") /* Burundi */
|
||||||
DEFINE_INT_CURR("BMD ") /* Burmuda */
|
DEFINE_INT_CURR("BMD ") /* Burmudian Dollar */
|
||||||
DEFINE_INT_CURR("BND ") /* Brunei */
|
DEFINE_INT_CURR("BND ") /* Brunei Dollar */
|
||||||
DEFINE_INT_CURR("BOP ") /* Bolivia */
|
DEFINE_INT_CURR("BOP ") /* Bolivian Boliviano */
|
||||||
DEFINE_INT_CURR("BRC ") /* Brazil */
|
DEFINE_INT_CURR("BPS ") /* Canton and Enderbury Islands */
|
||||||
DEFINE_INT_CURR("BSD ") /* Bahamas */
|
DEFINE_INT_CURR("BRC ") /* Brazil Real */
|
||||||
|
DEFINE_INT_CURR("BRL ") /* Brazil Cruzeiro */
|
||||||
|
DEFINE_INT_CURR("BRR ") /* Brazil Real */
|
||||||
|
DEFINE_INT_CURR("BSD ") /* Bahamas Dollar */
|
||||||
|
DEFINE_INT_CURR("BTN ") /* Bhutan Ngultrum */
|
||||||
DEFINE_INT_CURR("BUK ") /* Burma */
|
DEFINE_INT_CURR("BUK ") /* Burma */
|
||||||
DEFINE_INT_CURR("BWP ") /* Botswana */
|
DEFINE_INT_CURR("BWP ") /* Botswana Pula */
|
||||||
DEFINE_INT_CURR("BZD ") /* Belize */
|
DEFINE_INT_CURR("BZD ") /* Belize Dollar */
|
||||||
DEFINE_INT_CURR("CAD ") /* Canada */
|
DEFINE_INT_CURR("CAD ") /* Canadian Dollar */
|
||||||
DEFINE_INT_CURR("CHF ") /* Switzerland, Liechtenstein */
|
DEFINE_INT_CURR("CFP ") /* French Pacific Island Franc */
|
||||||
DEFINE_INT_CURR("CLP ") /* Chile */
|
DEFINE_INT_CURR("CHF ") /* Swiss Franc (Liechtenstein) */
|
||||||
DEFINE_INT_CURR("CNY ") /* China */
|
DEFINE_INT_CURR("CLP ") /* Chilean Peso */
|
||||||
DEFINE_INT_CURR("COP ") /* Colombia */
|
DEFINE_INT_CURR("CNY ") /* China Yuan Renminbi */
|
||||||
DEFINE_INT_CURR("CRC ") /* Costa Rica */
|
DEFINE_INT_CURR("COP ") /* Colombian Peso */
|
||||||
DEFINE_INT_CURR("CSK ") /* Czechoslovakia */
|
DEFINE_INT_CURR("CRC ") /* Costa Rican Colon */
|
||||||
DEFINE_INT_CURR("CUP ") /* Cuba */
|
DEFINE_INT_CURR("CUP ") /* Cuban Peso */
|
||||||
DEFINE_INT_CURR("CVE ") /* Cape Verde */
|
DEFINE_INT_CURR("CVE ") /* Cape Verde Escudo */
|
||||||
DEFINE_INT_CURR("CYP ") /* Cyprus */
|
DEFINE_INT_CURR("CYP ") /* Cypriot Pound */
|
||||||
DEFINE_INT_CURR("DEM ") /* Germany */
|
DEFINE_INT_CURR("CZK ") /* Czech Koruna */
|
||||||
DEFINE_INT_CURR("DJF ") /* Djibouti */
|
DEFINE_INT_CURR("DEM ") /* German Mark */
|
||||||
DEFINE_INT_CURR("DKK ") /* Denmark */
|
DEFINE_INT_CURR("DJF ") /* Djibouti Franc */
|
||||||
|
DEFINE_INT_CURR("DKK ") /* Danish Krone (Faroe Islands, Greenland) */
|
||||||
DEFINE_INT_CURR("DOP ") /* Dominican Republic */
|
DEFINE_INT_CURR("DOP ") /* Dominican Republic */
|
||||||
DEFINE_INT_CURR("DZD ") /* Algeria */
|
DEFINE_INT_CURR("DZD ") /* Algerian Dinar */
|
||||||
DEFINE_INT_CURR("ECS ") /* Ecuador */
|
DEFINE_INT_CURR("ECS ") /* Ecuadoran Sucre */
|
||||||
DEFINE_INT_CURR("EEK ") /* Estonia */
|
DEFINE_INT_CURR("EEK ") /* Estonian Kroon */
|
||||||
DEFINE_INT_CURR("EGP ") /* Egypt */
|
DEFINE_INT_CURR("EGP ") /* Egyptian Pound */
|
||||||
DEFINE_INT_CURR("ESP ") /* Spain */
|
DEFINE_INT_CURR("ESP ") /* Spanish Peseta */
|
||||||
DEFINE_INT_CURR("ETB ") /* Ethiopia */
|
DEFINE_INT_CURR("ETB ") /* Ethiopian Birr */
|
||||||
DEFINE_INT_CURR("FIM ") /* Finland */
|
DEFINE_INT_CURR("EUR ") /* European Union Euro */
|
||||||
DEFINE_INT_CURR("FJD ") /* Fiji */
|
DEFINE_INT_CURR("FIM ") /* Finnish Markka */
|
||||||
DEFINE_INT_CURR("FKP ") /* Falkland Islands (Malvinas) */
|
DEFINE_INT_CURR("FJD ") /* Fiji Dollar */
|
||||||
DEFINE_INT_CURR("FRF ") /* France */
|
DEFINE_INT_CURR("FKP ") /* Falkland Islands Pound (Malvinas) */
|
||||||
DEFINE_INT_CURR("GBP ") /* Great Britain */
|
DEFINE_INT_CURR("FRF ") /* French Franc */
|
||||||
DEFINE_INT_CURR("GHC ") /* Ghana */
|
DEFINE_INT_CURR("GBP ") /* British Pound */
|
||||||
DEFINE_INT_CURR("GIP ") /* Gibraltar */
|
DEFINE_INT_CURR("GEK ") /* Georgia Lari */
|
||||||
DEFINE_INT_CURR("GMD ") /* Gambia */
|
DEFINE_INT_CURR("GHC ") /* Ghana Cedi */
|
||||||
DEFINE_INT_CURR("GNS ") /* Guinea */
|
DEFINE_INT_CURR("GIP ") /* Gibraltar Pound */
|
||||||
DEFINE_INT_CURR("GQE ") /* Equatorial Guinea */
|
DEFINE_INT_CURR("GMD ") /* Gambian Dalasi */
|
||||||
DEFINE_INT_CURR("GRD ") /* Greece */
|
DEFINE_INT_CURR("GNS ") /* Guinea Syli */
|
||||||
DEFINE_INT_CURR("GTQ ") /* Guatemala */
|
DEFINE_INT_CURR("GQE ") /* Equatorial Guinea Ekwele */
|
||||||
DEFINE_INT_CURR("GWP ") /* Guinea-Bissau */
|
DEFINE_INT_CURR("GRD ") /* Greek Drachma */
|
||||||
DEFINE_INT_CURR("GYD ") /* Guyana */
|
DEFINE_INT_CURR("GTQ ") /* Guatemala Quetzal */
|
||||||
DEFINE_INT_CURR("HKD ") /* Hong Kong */
|
DEFINE_INT_CURR("GWP ") /* Guinea-Bissau Peso */
|
||||||
DEFINE_INT_CURR("HNL ") /* Honduras */
|
DEFINE_INT_CURR("GYD ") /* Guyana Dollar */
|
||||||
DEFINE_INT_CURR("HRD ") /* Croatia */
|
DEFINE_INT_CURR("HKD ") /* Hong Kong Dollar */
|
||||||
DEFINE_INT_CURR("HTG ") /* Haiti */
|
DEFINE_INT_CURR("HNL ") /* Honduras Lempira */
|
||||||
DEFINE_INT_CURR("HUF ") /* Hungary */
|
DEFINE_INT_CURR("HRK ") /* Croatia Kuna */
|
||||||
DEFINE_INT_CURR("IDR ") /* Indonesia */
|
DEFINE_INT_CURR("HTG ") /* Haiti Gourde */
|
||||||
DEFINE_INT_CURR("IEP ") /* Ireland */
|
DEFINE_INT_CURR("HUF ") /* Hungarian Forint */
|
||||||
DEFINE_INT_CURR("ILS ") /* Israel */
|
DEFINE_INT_CURR("IDR ") /* Indonesia Rupiah */
|
||||||
DEFINE_INT_CURR("INR ") /* India, Bhutan */
|
DEFINE_INT_CURR("IEP ") /* Irish Pound */
|
||||||
DEFINE_INT_CURR("IQD ") /* Iraq */
|
DEFINE_INT_CURR("ILS ") /* Israeli Shekel */
|
||||||
DEFINE_INT_CURR("IRR ") /* Iran */
|
DEFINE_INT_CURR("INR ") /* Indian Rupee (Bhutan) */
|
||||||
DEFINE_INT_CURR("ISK ") /* Iceland */
|
DEFINE_INT_CURR("IQD ") /* Iraqi Dinar */
|
||||||
DEFINE_INT_CURR("ITL ") /* Italy */
|
DEFINE_INT_CURR("IRR ") /* Iranian Rial */
|
||||||
DEFINE_INT_CURR("JMD ") /* Jamaica */
|
DEFINE_INT_CURR("ISK ") /* Iceland Krona */
|
||||||
DEFINE_INT_CURR("JOD ") /* Jordan */
|
DEFINE_INT_CURR("ITL ") /* Italian Lira (San Marino, Vatican City) */
|
||||||
DEFINE_INT_CURR("JPY ") /* Japan */
|
DEFINE_INT_CURR("JMD ") /* Jamaican Dollar */
|
||||||
DEFINE_INT_CURR("KES ") /* Kenya */
|
DEFINE_INT_CURR("JOD ") /* Jordanian Dinar */
|
||||||
DEFINE_INT_CURR("KHR ") /* Democratic Kampuchea */
|
DEFINE_INT_CURR("JPY ") /* Japanese Yen */
|
||||||
DEFINE_INT_CURR("KMF ") /* Comoros */
|
DEFINE_INT_CURR("KES ") /* Kenyan Shilling */
|
||||||
DEFINE_INT_CURR("KPW ") /* Democratic People's of Korea */
|
DEFINE_INT_CURR("KGS ") /* Kyrgyzstan Som */
|
||||||
DEFINE_INT_CURR("KRW ") /* Republic of Korea */
|
DEFINE_INT_CURR("KHR ") /* Democratic Kampuchea Riel */
|
||||||
DEFINE_INT_CURR("KWD ") /* Kuwait */
|
DEFINE_INT_CURR("KMF ") /* Comoros Franc */
|
||||||
|
DEFINE_INT_CURR("KPW ") /* Democratic People's of Korea Won */
|
||||||
|
DEFINE_INT_CURR("KRW ") /* Republic of Korea Won */
|
||||||
|
DEFINE_INT_CURR("KWD ") /* Kuwaiti Dinar */
|
||||||
DEFINE_INT_CURR("KYD ") /* Cayman Islands */
|
DEFINE_INT_CURR("KYD ") /* Cayman Islands */
|
||||||
DEFINE_INT_CURR("LAK ") /* Lao People's Democratic Republic */
|
DEFINE_INT_CURR("KZT ") /* Kazakhstan Tenge */
|
||||||
DEFINE_INT_CURR("LBP ") /* Lebanon */
|
DEFINE_INT_CURR("LAK ") /* Lao People's Democratic Republic New Kip */
|
||||||
DEFINE_INT_CURR("LKR ") /* Sri Lanka */
|
DEFINE_INT_CURR("LBP ") /* Lebanese Pound */
|
||||||
DEFINE_INT_CURR("LRD ") /* Liberia */
|
DEFINE_INT_CURR("LKR ") /* Sri Lankan Rupee */
|
||||||
DEFINE_INT_CURR("LSM ") /* Lesotho */
|
DEFINE_INT_CURR("LRD ") /* Liberian Dollar */
|
||||||
DEFINE_INT_CURR("LTL ") /* Lithuania */
|
DEFINE_INT_CURR("LSM ") /* Lesotho Maloti */
|
||||||
DEFINE_INT_CURR("LUF ") /* Luxembourg */
|
DEFINE_INT_CURR("LTL ") /* Lithuanian Litas */
|
||||||
DEFINE_INT_CURR("LVL ") /* Latvia */
|
DEFINE_INT_CURR("LUF ") /* Luxembourg Franc */
|
||||||
DEFINE_INT_CURR("LYD ") /* Libyan Arab Jamahiriya */
|
DEFINE_INT_CURR("LVL ") /* Latvia Lat */
|
||||||
DEFINE_INT_CURR("MAD ") /* Morocco */
|
DEFINE_INT_CURR("LYD ") /* Libyan Arab Jamahiriya Dinar */
|
||||||
DEFINE_INT_CURR("MGF ") /* Madagascar */
|
DEFINE_INT_CURR("MAD ") /* Moroccan Dirham */
|
||||||
DEFINE_INT_CURR("MLF ") /* Mali */
|
DEFINE_INT_CURR("MDL ") /* Moldova Lei */
|
||||||
DEFINE_INT_CURR("MNT ") /* Mongolia */
|
DEFINE_INT_CURR("MGF ") /* Madagasy Franc */
|
||||||
DEFINE_INT_CURR("MOP ") /* Macau */
|
DEFINE_INT_CURR("MLF ") /* Mali Franc */
|
||||||
DEFINE_INT_CURR("MRO ") /* Mauritania */
|
DEFINE_INT_CURR("MMK ") /* Myanmar Kyat */
|
||||||
DEFINE_INT_CURR("MTP ") /* Malta */
|
DEFINE_INT_CURR("MNT ") /* Mongolia Tugrik */
|
||||||
DEFINE_INT_CURR("MUR ") /* Mauritius */
|
DEFINE_INT_CURR("MOP ") /* Macau Pataca */
|
||||||
DEFINE_INT_CURR("MVR ") /* Maldives */
|
DEFINE_INT_CURR("MRO ") /* Mauritania Ouguiya */
|
||||||
DEFINE_INT_CURR("MWK ") /* Malawi */
|
DEFINE_INT_CURR("MTP ") /* Maltese Lira */
|
||||||
DEFINE_INT_CURR("MXP ") /* Mexico */
|
DEFINE_INT_CURR("MUR ") /* Mauritius Rupee */
|
||||||
DEFINE_INT_CURR("MYR ") /* Malaysia */
|
DEFINE_INT_CURR("MVR ") /* Maldives Rupee */
|
||||||
DEFINE_INT_CURR("MZM ") /* Mozambique */
|
DEFINE_INT_CURR("MWK ") /* Malawi Kwacha */
|
||||||
DEFINE_INT_CURR("NGN ") /* Nigeria */
|
DEFINE_INT_CURR("MXP ") /* Mexican Peso */
|
||||||
DEFINE_INT_CURR("NIC ") /* Nicaragua */
|
DEFINE_INT_CURR("MYR ") /* Malaysian Ringgit */
|
||||||
DEFINE_INT_CURR("NLG ") /* Netherlands */
|
DEFINE_INT_CURR("MZM ") /* Mozambique Metical */
|
||||||
DEFINE_INT_CURR("NOK ") /* Norway */
|
DEFINE_INT_CURR("NGN ") /* Nigeria Naira */
|
||||||
DEFINE_INT_CURR("NPR ") /* Nepal */
|
DEFINE_INT_CURR("NIC ") /* Nicaragua Cordoba */
|
||||||
DEFINE_INT_CURR("NZD ") /* New Zealand */
|
DEFINE_INT_CURR("NLG ") /* Netherlands Guilder */
|
||||||
DEFINE_INT_CURR("OMR ") /* Oman */
|
DEFINE_INT_CURR("NOK ") /* Norwegian Krone */
|
||||||
DEFINE_INT_CURR("PAB ") /* Panama */
|
DEFINE_INT_CURR("NPR ") /* Nepalese Rupee */
|
||||||
DEFINE_INT_CURR("PES ") /* Peru */
|
DEFINE_INT_CURR("NZD ") /* New Zealand Dollar */
|
||||||
DEFINE_INT_CURR("PGK ") /* Papau New Guinea */
|
DEFINE_INT_CURR("OMR ") /* Omani Rial */
|
||||||
DEFINE_INT_CURR("PHP ") /* Philippines */
|
DEFINE_INT_CURR("PAB ") /* Panamaniam Balboa */
|
||||||
DEFINE_INT_CURR("PKR ") /* Pakistan */
|
DEFINE_INT_CURR("PEN ") /* Peruvian New Sol */
|
||||||
DEFINE_INT_CURR("PLZ ") /* Poland */
|
DEFINE_INT_CURR("PGK ") /* Papau New Guinea Kina */
|
||||||
DEFINE_INT_CURR("PTE ") /* Portugal */
|
DEFINE_INT_CURR("PHP ") /* Philippines Peso */
|
||||||
DEFINE_INT_CURR("PYG ") /* Paraguay */
|
DEFINE_INT_CURR("PKR ") /* Pakistan Rupee */
|
||||||
DEFINE_INT_CURR("QAR ") /* Qatar */
|
DEFINE_INT_CURR("PLZ ") /* Polish Zloty */
|
||||||
DEFINE_INT_CURR("ROL ") /* Romania */
|
DEFINE_INT_CURR("PTE ") /* Portugese Escudo */
|
||||||
DEFINE_INT_CURR("RUR ") /* Russia */
|
DEFINE_INT_CURR("PYG ") /* Paraguay Guarani */
|
||||||
DEFINE_INT_CURR("RWF ") /* Rwanda */
|
DEFINE_INT_CURR("QAR ") /* Qatar Rial */
|
||||||
DEFINE_INT_CURR("SAR ") /* Saudi Arabia */
|
DEFINE_INT_CURR("ROL ") /* Romanian Leu */
|
||||||
DEFINE_INT_CURR("SBD ") /* Solomon Islands */
|
DEFINE_INT_CURR("RUR ") /* Russian Ruble */
|
||||||
DEFINE_INT_CURR("SCR ") /* Seychelles */
|
DEFINE_INT_CURR("RWF ") /* Rwanda Franc */
|
||||||
DEFINE_INT_CURR("SDP ") /* Sudan */
|
DEFINE_INT_CURR("SAR ") /* Saudi Arabia Riyal */
|
||||||
DEFINE_INT_CURR("SEK ") /* Sweden */
|
DEFINE_INT_CURR("SBD ") /* Solomon Islands Dollar */
|
||||||
DEFINE_INT_CURR("SGD ") /* Singapore */
|
DEFINE_INT_CURR("SCR ") /* Seychelles Rupee */
|
||||||
DEFINE_INT_CURR("SHP ") /* St. Helena */
|
DEFINE_INT_CURR("SDP ") /* Sudanese Pound */
|
||||||
DEFINE_INT_CURR("SIT ") /* Slovenia */
|
DEFINE_INT_CURR("SEK ") /* Swedish Krona */
|
||||||
DEFINE_INT_CURR("SLL ") /* Sierra Leone */
|
DEFINE_INT_CURR("SGD ") /* Singapore Dollar */
|
||||||
DEFINE_INT_CURR("SOS ") /* Somalia */
|
DEFINE_INT_CURR("SHP ") /* St. Helena Pound */
|
||||||
DEFINE_INT_CURR("SRG ") /* Suriname */
|
DEFINE_INT_CURR("SIT ") /* Slovenian Tolar */
|
||||||
DEFINE_INT_CURR("STD ") /* Sao Tome and Principe */
|
DEFINE_INT_CURR("SKK ") /* Slovakian Koruna */
|
||||||
DEFINE_INT_CURR("SUR ") /* Ukrainian, Byelorussion */
|
DEFINE_INT_CURR("SLL ") /* Sierra Leone Leone */
|
||||||
DEFINE_INT_CURR("SVC ") /* El Salvador */
|
DEFINE_INT_CURR("SOS ") /* Somalia Schilling */
|
||||||
DEFINE_INT_CURR("SYP ") /* Syrian Arab Republic */
|
DEFINE_INT_CURR("SRG ") /* Suriname Guilder */
|
||||||
DEFINE_INT_CURR("SZL ") /* Swaziland */
|
DEFINE_INT_CURR("STD ") /* Sao Tome and Principe Dobra */
|
||||||
DEFINE_INT_CURR("THB ") /* Thailand */
|
DEFINE_INT_CURR("SUR ") /* Soviet Union Rubel (Ukrainian, Byelorussion) */
|
||||||
DEFINE_INT_CURR("TND ") /* Tunisia */
|
DEFINE_INT_CURR("SVC ") /* El Salvador Colon */
|
||||||
DEFINE_INT_CURR("TOP ") /* Tonga */
|
DEFINE_INT_CURR("SYP ") /* Syrian Arab Republic Pound */
|
||||||
DEFINE_INT_CURR("TPE ") /* East Timor */
|
DEFINE_INT_CURR("SZL ") /* Swaziland Lilangeni */
|
||||||
DEFINE_INT_CURR("TRL ") /* Turkey */
|
DEFINE_INT_CURR("THB ") /* Thai Baht */
|
||||||
|
DEFINE_INT_CURR("TMM ") /* Turkmenistan Manet */
|
||||||
|
DEFINE_INT_CURR("TND ") /* Tunisian Dinar */
|
||||||
|
DEFINE_INT_CURR("TOP ") /* Tonga Pa'Anga */
|
||||||
|
DEFINE_INT_CURR("TPE ") /* East Timor Escudo */
|
||||||
|
DEFINE_INT_CURR("TRL ") /* Turkish Lira */
|
||||||
DEFINE_INT_CURR("TTD ") /* Trinidad and Tobago */
|
DEFINE_INT_CURR("TTD ") /* Trinidad and Tobago */
|
||||||
DEFINE_INT_CURR("TWD ") /* Taiwan, Province of China */
|
DEFINE_INT_CURR("TWD ") /* Taiwan, Province of China Dollar */
|
||||||
DEFINE_INT_CURR("TZS ") /* United Republic of Tanzania */
|
DEFINE_INT_CURR("TZS ") /* United Republic of Tanzania Shilling */
|
||||||
DEFINE_INT_CURR("UGS ") /* Uganda */
|
DEFINE_INT_CURR("UAK ") /* Ukraine Hryvna */
|
||||||
DEFINE_INT_CURR("USD ") /* United States */
|
DEFINE_INT_CURR("UGS ") /* Ugandan Shilling */
|
||||||
DEFINE_INT_CURR("UYP ") /* Uruguay */
|
DEFINE_INT_CURR("USD ") /* United States Dollar */
|
||||||
DEFINE_INT_CURR("VEB ") /* Venezuela */
|
DEFINE_INT_CURR("UYP ") /* Uruguay Peso */
|
||||||
DEFINE_INT_CURR("VND ") /* Viet Nam */
|
DEFINE_INT_CURR("UYU ") /* Uruguay New Peso */
|
||||||
DEFINE_INT_CURR("VUV ") /* Vanuatu */
|
DEFINE_INT_CURR("UZS ") /* Uzbekistan Sum */
|
||||||
DEFINE_INT_CURR("WST ") /* Samoa */
|
DEFINE_INT_CURR("VEB ") /* Venezuelan Bolivar */
|
||||||
DEFINE_INT_CURR("XAF ") /* United Republic of Cameroon, Central African Republic, Chad, Congo, Gabon */
|
DEFINE_INT_CURR("VND ") /* Viet Nam Dong */
|
||||||
DEFINE_INT_CURR("XCD ") /* Antiqua, Dominica, Grenada, Montserrat, St. Kitts-Nevis-Anguilla, Saint Lucia, Saint Vincent and the Grenadines */
|
DEFINE_INT_CURR("VUV ") /* Vanuatu Vatu */
|
||||||
DEFINE_INT_CURR("XOF ") /* Benin, Ivory Coast, Niger, Senegal, Togo, Upper Volta */
|
DEFINE_INT_CURR("WST ") /* Samoa Tala */
|
||||||
|
DEFINE_INT_CURR("XAF ") /* Central African Franc (United Republic of Cameroon, Central African Republic, Chad, Congo, Gabon) */
|
||||||
|
DEFINE_INT_CURR("XCD ") /* East Caribbean Dollar (Antiqua, Dominica, Grenada, Montserrat, St. Kitts-Nevis-Anguilla, Saint Lucia, Saint Vincent and the Grenadines) */
|
||||||
|
DEFINE_INT_CURR("XDS ") /* St. Christopher Dollar */
|
||||||
|
DEFINE_INT_CURR("XOF ") /* West African Franc (Benin, Ivory Coast, Niger, Senegal, Togo, Upper Volta) */
|
||||||
DEFINE_INT_CURR("XPF ") /* French polynesia, New Caledonia, Wallis and Futuna Islands */
|
DEFINE_INT_CURR("XPF ") /* French polynesia, New Caledonia, Wallis and Futuna Islands */
|
||||||
DEFINE_INT_CURR("YDD ") /* Democratic Yemen */
|
DEFINE_INT_CURR("YDD ") /* Yemini Dinar (Democratic Yemen) */
|
||||||
DEFINE_INT_CURR("YER ") /* Yemen */
|
DEFINE_INT_CURR("YER ") /* Yemeni Rial */
|
||||||
DEFINE_INT_CURR("YUD ") /* Yugoslavia */
|
DEFINE_INT_CURR("ZAR ") /* South Africa Rand (Lesotho, Namibia) */
|
||||||
DEFINE_INT_CURR("ZAL ") /* South Africa */
|
DEFINE_INT_CURR("ZMK ") /* Zambian Kwacha */
|
||||||
DEFINE_INT_CURR("ZAR ") /* Lesotho, Namibia */
|
DEFINE_INT_CURR("ZRZ ") /* Zaire Zaire */
|
||||||
DEFINE_INT_CURR("ZMK ") /* Zambia */
|
DEFINE_INT_CURR("ZWD ") /* Zimbabwe Dollar */
|
||||||
DEFINE_INT_CURR("ZRZ ") /* Zaire */
|
|
||||||
DEFINE_INT_CURR("ZWD ") /* Zimbabwe */
|
|
||||||
|
@ -127,7 +127,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
|
|||||||
#endif
|
#endif
|
||||||
filedata = (void *) __mmap ((caddr_t) 0, st.st_size, PROT_READ,
|
filedata = (void *) __mmap ((caddr_t) 0, st.st_size, PROT_READ,
|
||||||
MAP_FILE|MAP_COPY|MAP_INHERIT, fd, 0);
|
MAP_FILE|MAP_COPY|MAP_INHERIT, fd, 0);
|
||||||
if (filedata == MAP_FAILED)
|
if ((void *) filedata == MAP_FAILED)
|
||||||
{
|
{
|
||||||
if (errno == ENOSYS)
|
if (errno == ENOSYS)
|
||||||
{
|
{
|
||||||
|
@ -1167,19 +1167,131 @@ translations from the file
|
|||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
From the above descriptions it should be clear which component of this
|
From the above descriptions it should be clear which component of this
|
||||||
filename is determined fromby which source.
|
filename is determined by which source.
|
||||||
|
|
||||||
@c Describe:
|
In the above example we assumed that the @code{LANGUAGE} environment
|
||||||
@c * message inheritence
|
variable to @code{de}. This might be an appropriate selection but what
|
||||||
@c * locale aliasing
|
happens if the user wants to use @code{LC_ALL} because of the wider
|
||||||
@c * character set dependence
|
usability and here the required value is @code{de_DE.ISO-8859-1}? We
|
||||||
|
already mentioned above that a situation like this is not infrequent.
|
||||||
|
E.g., a person might prefer reading a dialect and if this is not
|
||||||
|
available fall back on the standard language.
|
||||||
|
|
||||||
|
The @code{gettext} functions know about situations like this and can
|
||||||
|
handle them gracefully. The functions recognize the format of the value
|
||||||
|
of the environment variable. It can split the value is different pieces
|
||||||
|
and by leaving out the only or the other part it can construct new
|
||||||
|
values. This happens of course in a predictable way. To understand
|
||||||
|
this one must know the format of the environment variable value. There
|
||||||
|
are to more or less standardized forms:
|
||||||
|
|
||||||
|
@table @emph
|
||||||
|
@item X/Open Format
|
||||||
|
@code{language[_territory[.codeset]][@@modifier]}
|
||||||
|
|
||||||
|
@item CEN Format (European Community Standard)
|
||||||
|
@code{language[_territory][+audience][+special][,[sponsor][_revision]]}
|
||||||
|
@end table
|
||||||
|
|
||||||
|
The functions will automatically recognize which format is used. Less
|
||||||
|
specific locale names will be stripped of in the order of the following
|
||||||
|
list:
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
@code{revision}
|
||||||
|
@item
|
||||||
|
@code{sponsor}
|
||||||
|
@item
|
||||||
|
@code{special}
|
||||||
|
@item
|
||||||
|
@code{codeset}
|
||||||
|
@item
|
||||||
|
@code{normalized codeset}
|
||||||
|
@item
|
||||||
|
@code{territory}
|
||||||
|
@item
|
||||||
|
@code{audience}/@code{modifier}
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
From the last entry one can see that the meaning of the @code{modifer}
|
||||||
|
field in the X/Open format and the @code{audience} format have the same
|
||||||
|
meaning. Beside one can see that the @code{language} field for obvious
|
||||||
|
reasons never will be dropped.
|
||||||
|
|
||||||
|
The only new thing is the @code{normalized codeset} entry. This is
|
||||||
|
another goodie which is introduced to help reducing the chaos which
|
||||||
|
derives from the inability of the people to standardize the names of
|
||||||
|
character sets. Instead of @w{ISO-8859-1} one can often see @w{8859-1},
|
||||||
|
@w{88591}, @w{iso8859-1}, or @w{iso_8859-1}. The @code{normalized
|
||||||
|
codeset} value is generated from the user-provided character set name by
|
||||||
|
applying the following rules:
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
Remove all characters beside numbers and letters.
|
||||||
|
@item
|
||||||
|
Fold letters to lowercase.
|
||||||
|
@item
|
||||||
|
If the same only contains digits prepend the string @code{"iso"}.
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
So all of the above name will be normalized to @code{iso88591}. This
|
||||||
|
allows the program user much more freely choosing the locale name.
|
||||||
|
|
||||||
|
Even this extended functionality still does not help to solve the
|
||||||
|
problem that completely different names can be used to denote the same
|
||||||
|
locale (e.g., @code{de} and @code{german}). To be of help in this
|
||||||
|
situation the locale implementation and also the @code{gettext}
|
||||||
|
functions know about aliases.
|
||||||
|
|
||||||
|
The file @file{/usr/share/locale/locale.alias} (replace @file{/usr} with
|
||||||
|
whatever prefix you used for configuring the C library) contains a
|
||||||
|
mapping of alternative names to more regular names. The system manager
|
||||||
|
is free to add new entries to fill her/his own needs. The selected
|
||||||
|
locale from the environment is compared with the entries in the first
|
||||||
|
column of this file ignoring the case. If they match the value of the
|
||||||
|
second column is used instead for the further handling.
|
||||||
|
|
||||||
|
In the description of the format of the environment variables we already
|
||||||
|
mentioned the character set as a factor in the selection of the message
|
||||||
|
catalog. In fact, only catalogs which contain text written using the
|
||||||
|
character set of the system/program can be used (directly; there will
|
||||||
|
come a solution for this some day). This means for the user that s/he
|
||||||
|
will always have to take care for this. If in the collection of the
|
||||||
|
message catalogs there are files for the same language but coded using
|
||||||
|
different character sets the user has to be careful.
|
||||||
|
|
||||||
|
|
||||||
@node Helper programs for gettext
|
@node Helper programs for gettext
|
||||||
@subsection Programs to handle message catalogs for @code{gettext}
|
@subsection Programs to handle message catalogs for @code{gettext}
|
||||||
|
|
||||||
@c Describe:
|
The GNU C Library does not contain the source code for the programs to
|
||||||
@c * msgfmt
|
handle message catalogs for the @code{gettext} functions. As part of
|
||||||
@c * xgettext
|
the GNU project the GNU gettext package contains everything the
|
||||||
@c Mention:
|
developer needs. The functionality provided by the tools in this
|
||||||
@c * other programs from GNU gettext
|
package by far exceeds the abilities of the @code{gencat} program
|
||||||
|
described above for the @code{catgets} functions.
|
||||||
|
|
||||||
|
There is a program @code{msgfmt} which is the equivalent program to the
|
||||||
|
@code{gencat} program. It generates from the human-readable and
|
||||||
|
-editable form of the message catalog a binary file which can be used by
|
||||||
|
the @code{gettext} functions. But there are several more programs
|
||||||
|
available.
|
||||||
|
|
||||||
|
The @code{xgettext} program can be used to automatically extract the
|
||||||
|
translatable messages from a source file. I.e., the programmer need not
|
||||||
|
take care for the translations and the list of messages which have to be
|
||||||
|
translated. S/He will simply wrap the translatable string in calls to
|
||||||
|
@code{gettext} et.al and the rest will be done by @code{xgettext}. This
|
||||||
|
program has a lot of option which help to customize the output or do
|
||||||
|
help to understand the input better.
|
||||||
|
|
||||||
|
Other programs help to manage development cycle when new messages appear
|
||||||
|
in the source files or when a new translation of the messages appear.
|
||||||
|
here it should only be noted that using all the tools in GNu gettext it
|
||||||
|
is possible to @emph{completely} automize the handling of message
|
||||||
|
catalog. Beside marking the translatable string in the source code and
|
||||||
|
generating the translations the developers do not have anything to do
|
||||||
|
themself.
|
||||||
|
@ -4705,7 +4705,7 @@ identities (void)
|
|||||||
identities1_test (0, 0);
|
identities1_test (0, 0);
|
||||||
identities1_test (-1, CHOOSE (1e-18L, 0, 1e-7));
|
identities1_test (-1, CHOOSE (1e-18L, 0, 1e-7));
|
||||||
|
|
||||||
identities2_test (0.2L, CHOOSE (0, 1e-16, 0));
|
identities2_test (0.2L, CHOOSE (1e-19L, 1e-16, 0));
|
||||||
identities2_test (0.9L, CHOOSE (0, 1e-15, 0));
|
identities2_test (0.9L, CHOOSE (0, 1e-15, 0));
|
||||||
identities2_test (0, 0);
|
identities2_test (0, 0);
|
||||||
identities2_test (-1, CHOOSE (1e-18L, 1e-15, 0));
|
identities2_test (-1, CHOOSE (1e-18L, 1e-15, 0));
|
||||||
|
830
po/libc.pot
830
po/libc.pot
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "../stdio-common/_itoa.h"
|
#include <stdio-common/_itoa.h>
|
||||||
|
|
||||||
/* Variable to synchronize work. */
|
/* Variable to synchronize work. */
|
||||||
char *__getopt_nonoption_flags;
|
char *__getopt_nonoption_flags;
|
||||||
@ -40,13 +40,13 @@ extern pid_t __libc_pid;
|
|||||||
application it does not exist anymore since it was saved for the use
|
application it does not exist anymore since it was saved for the use
|
||||||
in getopt. */
|
in getopt. */
|
||||||
void
|
void
|
||||||
__getopt_clean_environment (void)
|
__getopt_clean_environment (char **env)
|
||||||
{
|
{
|
||||||
/* Bash 2.0 puts a special variable in the environment for each
|
/* Bash 2.0 puts a special variable in the environment for each
|
||||||
command it runs, specifying which ARGV elements are the results
|
command it runs, specifying which ARGV elements are the results
|
||||||
of file name wildcard expansion and therefore should not be
|
of file name wildcard expansion and therefore should not be
|
||||||
considered as options. */
|
considered as options. */
|
||||||
static const char envvar_tail[] = "_GNU_nonoption_argv_flags_";
|
static const char envvar_tail[] = "_GNU_nonoption_argv_flags_=";
|
||||||
char var[100];
|
char var[100];
|
||||||
char *cp, **ep;
|
char *cp, **ep;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -56,19 +56,19 @@ __getopt_clean_environment (void)
|
|||||||
if (__libc_pid == 0)
|
if (__libc_pid == 0)
|
||||||
__libc_pid = getpid ();
|
__libc_pid = getpid ();
|
||||||
|
|
||||||
/* Construct "_<PID>_GNU_nonoption_argv_flags_" string. */
|
/* Construct "_<PID>_GNU_nonoption_argv_flags_=" string. */
|
||||||
cp = memcpy (&var[sizeof (var) - sizeof (envvar_tail)], envvar_tail,
|
cp = memcpy (&var[sizeof (var) - sizeof (envvar_tail)], envvar_tail,
|
||||||
sizeof (envvar_tail));
|
sizeof (envvar_tail));
|
||||||
cp = _itoa_word (__libc_pid, cp, 10, 0);
|
cp = _itoa_word (__libc_pid, cp, 10, 0);
|
||||||
*--cp = '_';
|
*--cp = '_';
|
||||||
len = (var + sizeof (var) - 1) - cp;
|
len = (var + sizeof (var) - 1) - cp;
|
||||||
|
|
||||||
for (ep = __environ; *ep != NULL; ++ep)
|
for (ep = env; *ep != NULL; ++ep)
|
||||||
if (!strncmp (*ep, cp, len) && (*ep)[len] == '=')
|
if (!strncmp (*ep, cp, len))
|
||||||
{
|
{
|
||||||
/* Found it. Store this pointer and move later ones back. */
|
/* Found it. Store this pointer and move later ones back. */
|
||||||
char **dp = ep;
|
char **dp = ep;
|
||||||
__getopt_nonoption_flags = &(*ep)[len + 1];
|
__getopt_nonoption_flags = &(*ep)[len];
|
||||||
do
|
do
|
||||||
dp[0] = dp[1];
|
dp[0] = dp[1];
|
||||||
while (*dp++);
|
while (*dp++);
|
||||||
|
@ -252,6 +252,11 @@ extern char *alloca ();
|
|||||||
#undef GLOB_PERIOD
|
#undef GLOB_PERIOD
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
|
|
||||||
|
static
|
||||||
|
#if __GNUC__ - 0 >= 2
|
||||||
|
inline
|
||||||
|
#endif
|
||||||
|
const char *next_brace_sub __P ((const char *begin));
|
||||||
static int glob_in_dir __P ((const char *pattern, const char *directory,
|
static int glob_in_dir __P ((const char *pattern, const char *directory,
|
||||||
int flags,
|
int flags,
|
||||||
int (*errfunc) __P ((const char *, int)),
|
int (*errfunc) __P ((const char *, int)),
|
||||||
|
@ -34,10 +34,12 @@ extern char **_dl_argv;
|
|||||||
extern char **_environ;
|
extern char **_environ;
|
||||||
extern size_t _dl_pagesize;
|
extern size_t _dl_pagesize;
|
||||||
extern const char *_dl_platform;
|
extern const char *_dl_platform;
|
||||||
|
extern unsigned long _dl_hwcap;
|
||||||
extern size_t _dl_platformlen;
|
extern size_t _dl_platformlen;
|
||||||
extern void _end;
|
extern void _end;
|
||||||
extern void ENTRY_POINT (void);
|
extern void ENTRY_POINT (void);
|
||||||
|
|
||||||
|
ElfW(Addr) _dl_base_addr;
|
||||||
int __libc_enable_secure;
|
int __libc_enable_secure;
|
||||||
int __libc_multiple_libcs; /* Defining this here avoids the inclusion
|
int __libc_multiple_libcs; /* Defining this here avoids the inclusion
|
||||||
of init-first. */
|
of init-first. */
|
||||||
@ -87,6 +89,9 @@ _dl_sysdep_start (void **start_argptr,
|
|||||||
case AT_ENTRY:
|
case AT_ENTRY:
|
||||||
user_entry = av->a_un.a_val;
|
user_entry = av->a_un.a_val;
|
||||||
break;
|
break;
|
||||||
|
case AT_BASE:
|
||||||
|
_dl_base_addr = av->a_un.a_val;
|
||||||
|
break;
|
||||||
case AT_UID:
|
case AT_UID:
|
||||||
uid = av->a_un.a_val;
|
uid = av->a_un.a_val;
|
||||||
break;
|
break;
|
||||||
@ -103,7 +108,7 @@ _dl_sysdep_start (void **start_argptr,
|
|||||||
_dl_platform = av->a_un.a_ptr;
|
_dl_platform = av->a_un.a_ptr;
|
||||||
break;
|
break;
|
||||||
case AT_HWCAP:
|
case AT_HWCAP:
|
||||||
/* Well, what shall we use? A string or an integer with bits? */
|
_dl_hwcap = av->a_un.a_val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +192,12 @@ _dl_show_auxv (void)
|
|||||||
16, 0),
|
16, 0),
|
||||||
"\n", NULL);
|
"\n", NULL);
|
||||||
break;
|
break;
|
||||||
|
case AT_BASE:
|
||||||
|
_dl_sysdep_message ("AT_BASE: 0x",
|
||||||
|
_itoa_word (av->a_un.a_val, buf + sizeof buf - 1,
|
||||||
|
16, 0),
|
||||||
|
"\n", NULL);
|
||||||
|
break;
|
||||||
case AT_UID:
|
case AT_UID:
|
||||||
_dl_sysdep_message ("AT_UID: ",
|
_dl_sysdep_message ("AT_UID: ",
|
||||||
_itoa_word (av->a_un.a_val, buf + sizeof buf - 1,
|
_itoa_word (av->a_un.a_val, buf + sizeof buf - 1,
|
||||||
@ -215,10 +226,9 @@ _dl_show_auxv (void)
|
|||||||
_dl_sysdep_message ("AT_PLATFORM: ", av->a_un.a_ptr, NULL);
|
_dl_sysdep_message ("AT_PLATFORM: ", av->a_un.a_ptr, NULL);
|
||||||
break;
|
break;
|
||||||
case AT_HWCAP:
|
case AT_HWCAP:
|
||||||
/* Well, what shall we use? A string or an integer with bits? */
|
|
||||||
_dl_sysdep_message ("AT_HWCAP: ",
|
_dl_sysdep_message ("AT_HWCAP: ",
|
||||||
_itoa_word (av->a_un.a_val, buf + sizeof buf - 1,
|
_itoa_word (av->a_un.a_val, buf + sizeof buf - 1,
|
||||||
10, 0),
|
16, 0),
|
||||||
"\n", NULL);
|
"\n", NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -57,20 +57,12 @@ static inline Elf32_Addr __attribute__ ((unused))
|
|||||||
elf_machine_load_address (void)
|
elf_machine_load_address (void)
|
||||||
{
|
{
|
||||||
Elf32_Addr addr;
|
Elf32_Addr addr;
|
||||||
asm (" call .Lhere\n"
|
asm (" call 1f\n"
|
||||||
".Lhere: popl %0\n"
|
"1: popl %0\n"
|
||||||
" subl $.Lhere, %0"
|
" subl 1b@GOT(%%ebx), %0"
|
||||||
: "=r" (addr));
|
: "=r" (addr));
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
/* The `subl' insn above will contain an R_386_32 relocation entry
|
|
||||||
intended to insert the run-time address of the label `.Lhere'.
|
|
||||||
This will be the first relocation in the text of the dynamic linker;
|
|
||||||
we skip it to avoid trying to modify read-only text in this early stage. */
|
|
||||||
#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
|
|
||||||
++(const Elf32_Rel *) (dynamic_info)[DT_REL]->d_un.d_ptr; \
|
|
||||||
(dynamic_info)[DT_RELSZ]->d_un.d_val -= sizeof (Elf32_Rel);
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PROF
|
#ifndef PROF
|
||||||
/* We add a declaration of this function here so that in dl-runtime.c
|
/* We add a declaration of this function here so that in dl-runtime.c
|
||||||
@ -132,6 +124,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
|||||||
# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
|
# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
|
||||||
.globl _dl_runtime_resolve
|
.globl _dl_runtime_resolve
|
||||||
.type _dl_runtime_resolve, @function
|
.type _dl_runtime_resolve, @function
|
||||||
|
.align 16
|
||||||
_dl_runtime_resolve:
|
_dl_runtime_resolve:
|
||||||
pushl %eax # Preserve registers otherwise clobbered.
|
pushl %eax # Preserve registers otherwise clobbered.
|
||||||
pushl %ecx
|
pushl %ecx
|
||||||
@ -147,6 +140,7 @@ _dl_runtime_resolve:
|
|||||||
|
|
||||||
.globl _dl_runtime_profile
|
.globl _dl_runtime_profile
|
||||||
.type _dl_runtime_profile, @function
|
.type _dl_runtime_profile, @function
|
||||||
|
.align 16
|
||||||
_dl_runtime_profile:
|
_dl_runtime_profile:
|
||||||
pushl %eax # Preserve registers otherwise clobbered.
|
pushl %eax # Preserve registers otherwise clobbered.
|
||||||
pushl %ecx
|
pushl %ecx
|
||||||
@ -167,6 +161,7 @@ _dl_runtime_profile:
|
|||||||
.globl _dl_runtime_profile
|
.globl _dl_runtime_profile
|
||||||
.type _dl_runtime_resolve, @function
|
.type _dl_runtime_resolve, @function
|
||||||
.type _dl_runtime_profile, @function
|
.type _dl_runtime_profile, @function
|
||||||
|
.align 16
|
||||||
_dl_runtime_resolve:
|
_dl_runtime_resolve:
|
||||||
_dl_runtime_profile:
|
_dl_runtime_profile:
|
||||||
pushl %eax # Preserve registers otherwise clobbered.
|
pushl %eax # Preserve registers otherwise clobbered.
|
||||||
|
@ -73,6 +73,10 @@
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
|
#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
|
||||||
|
|
||||||
|
/* The gcc, version 2.7 or below, has problems with all this inlining
|
||||||
|
code. So disable it for this version of the compiler. */
|
||||||
|
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 7)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
# define __MATH_INLINE __inline
|
# define __MATH_INLINE __inline
|
||||||
#else
|
#else
|
||||||
@ -154,6 +158,80 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Miscellaneous functions */
|
||||||
|
|
||||||
|
__inline_mathcode (__sgn, __x, \
|
||||||
|
return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0))
|
||||||
|
|
||||||
|
__inline_mathcode (__pow2, __x, \
|
||||||
|
register long double __value; \
|
||||||
|
register long double __exponent; \
|
||||||
|
long int __p = (long int) __x; \
|
||||||
|
if (__x == (long double) __p) \
|
||||||
|
{ \
|
||||||
|
__asm __volatile__ \
|
||||||
|
("fscale" \
|
||||||
|
: "=t" (__value) : "0" (1.0), "u" (__x)); \
|
||||||
|
return __value; \
|
||||||
|
} \
|
||||||
|
__asm __volatile__ \
|
||||||
|
("fldl %%st(0)\n\t" \
|
||||||
|
"frndint # int(x)\n\t" \
|
||||||
|
"fxch\n\t" \
|
||||||
|
"fsub %%st(1) # fract(x)\n\t" \
|
||||||
|
"f2xm1 # 2^(fract(x)) - 1\n\t" \
|
||||||
|
: "=t" (__value), "=u" (__exponent) : "0" (__x)); \
|
||||||
|
__value += 1.0; \
|
||||||
|
__asm __volatile__ \
|
||||||
|
("fscale" \
|
||||||
|
: "=t" (__value) : "0" (__value), "u" (__exponent)); \
|
||||||
|
return __value)
|
||||||
|
|
||||||
|
#define __sincos_code \
|
||||||
|
register long double __cosr; \
|
||||||
|
register long double __sinr; \
|
||||||
|
__asm __volatile__ \
|
||||||
|
("fsincos\n\t" \
|
||||||
|
"fnstsw %%ax\n\t" \
|
||||||
|
"testl $0x400, %%eax\n\t" \
|
||||||
|
"jz 1f\n\t" \
|
||||||
|
"fldpi\n\t" \
|
||||||
|
"fadd %%st(0)\n\t" \
|
||||||
|
"fxch %%st(1)\n\t" \
|
||||||
|
"2: fprem1\n\t" \
|
||||||
|
"fnstsw %%ax\n\t" \
|
||||||
|
"testl $0x400, %%eax\n\t" \
|
||||||
|
"jnz 2b\n\t" \
|
||||||
|
"fstp %%st(1)\n\t" \
|
||||||
|
"fsincos\n\t" \
|
||||||
|
"1:" \
|
||||||
|
: "=t" (__cosr), "=u" (__sinr) : "0" (__x)); \
|
||||||
|
*__sinx = __sinr; \
|
||||||
|
*__cosx = __cosr
|
||||||
|
|
||||||
|
__MATH_INLINE void __sincos (double __x, double *__sinx, double *__cosx);
|
||||||
|
__MATH_INLINE void
|
||||||
|
__sincos (double __x, double *__sinx, double *__cosx)
|
||||||
|
{
|
||||||
|
__sincos_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
__MATH_INLINE void __sincosf (float __x, float *__sinx, float *__cosx);
|
||||||
|
__MATH_INLINE void
|
||||||
|
__sincosf (float __x, float *__sinx, float *__cosx)
|
||||||
|
{
|
||||||
|
__sincos_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
__MATH_INLINE void __sincosl (long double __x, long double *__sinx,
|
||||||
|
long double *__cosx);
|
||||||
|
__MATH_INLINE void
|
||||||
|
__sincosl (long double __x, long double *__sinx, long double *__cosx)
|
||||||
|
{
|
||||||
|
__sincos_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Optimized inline implementation, sometimes with reduced precision
|
/* Optimized inline implementation, sometimes with reduced precision
|
||||||
and/or argument range. */
|
and/or argument range. */
|
||||||
|
|
||||||
@ -278,10 +356,10 @@ __inline_mathop (sqrt, "fsqrt")
|
|||||||
__inline_mathop_ (long double, __sqrtl, "fsqrt")
|
__inline_mathop_ (long double, __sqrtl, "fsqrt")
|
||||||
|
|
||||||
#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 8)
|
#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 8)
|
||||||
__inline_mathcode_ (fabs, __x, return __builtin_fabs (__x))
|
__inline_mathcode_ (double, fabs, __x, return __builtin_fabs (__x))
|
||||||
__inline_mathcode_ (fabsf, __x, return __builtin_fabsf (__x))
|
__inline_mathcode_ (float, fabsf, __x, return __builtin_fabsf (__x))
|
||||||
__inline_mathcode_ (fabsl, __x, return __builtin_fabsl (__x))
|
__inline_mathcode_ (long double, fabsl, __x, return __builtin_fabsl (__x))
|
||||||
__inline_mathcode_ (__fabsl, __x, return __builtin_fabsl (__x))
|
__inline_mathcode_ (long double, __fabsl, __x, return __builtin_fabsl (__x))
|
||||||
#else
|
#else
|
||||||
__inline_mathop (fabs, "fabs")
|
__inline_mathop (fabs, "fabs")
|
||||||
__inline_mathop_ (long double, __fabsl, "fabs")
|
__inline_mathop_ (long double, __fabsl, "fabs")
|
||||||
@ -356,7 +434,7 @@ ldexp (double __x, int __y)
|
|||||||
/* Optimized versions for some non-standardized functions. */
|
/* Optimized versions for some non-standardized functions. */
|
||||||
#if defined __USE_ISOC9X || defined __USE_MISC
|
#if defined __USE_ISOC9X || defined __USE_MISC
|
||||||
|
|
||||||
__inline_mathop_decl (log2, "fyl2x", "u" (1.0), "0" (__x) : "st(1)")
|
__inline_mathop(log2, "fld1; fxch; fyl2x")
|
||||||
|
|
||||||
__inline_mathcode (expm1, __x, __expm1_code)
|
__inline_mathcode (expm1, __x, __expm1_code)
|
||||||
|
|
||||||
@ -443,15 +521,12 @@ __finite (double __x)
|
|||||||
("orl $0x800fffff, %0\n\t"
|
("orl $0x800fffff, %0\n\t"
|
||||||
"incl %0\n\t"
|
"incl %0\n\t"
|
||||||
"shrl $31, %0"
|
"shrl $31, %0"
|
||||||
: "=q" (__result) : "0" (((int *) &__x)[1]));
|
: "=q" (__result) : "0" (((int *) &__x)[1]) : "cc");
|
||||||
return __result;
|
return __result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Miscellaneous functions */
|
/* Miscellaneous functions */
|
||||||
|
|
||||||
__inline_mathcode (__sgn, __x, \
|
|
||||||
return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0))
|
|
||||||
|
|
||||||
__inline_mathcode (__coshm1, __x, \
|
__inline_mathcode (__coshm1, __x, \
|
||||||
register long double __exm1 = __expm1l (__fabsl (__x)); \
|
register long double __exm1 = __expm1l (__fabsl (__x)); \
|
||||||
return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1)
|
return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1)
|
||||||
@ -459,69 +534,6 @@ __inline_mathcode (__coshm1, __x, \
|
|||||||
__inline_mathcode (__acosh1p, __x, \
|
__inline_mathcode (__acosh1p, __x, \
|
||||||
return log1pl (__x + __sqrtl (__x) * __sqrtl (__x + 2.0)))
|
return log1pl (__x + __sqrtl (__x) * __sqrtl (__x + 2.0)))
|
||||||
|
|
||||||
__inline_mathcode (__pow2, __x, \
|
|
||||||
register long double __value; \
|
|
||||||
register long double __exponent; \
|
|
||||||
long int __p = (long int) __x; \
|
|
||||||
if (__x == (long double) __p) \
|
|
||||||
return ldexpl (1.0, __p); \
|
|
||||||
__asm __volatile__ \
|
|
||||||
("fldl %%st(0)\n\t" \
|
|
||||||
"frndint # int(x)\n\t" \
|
|
||||||
"fxch\n\t" \
|
|
||||||
"fsub %%st(1) # fract(x)\n\t" \
|
|
||||||
"f2xm1 # 2^(fract(x)) - 1\n\t" \
|
|
||||||
: "=t" (__value), "=u" (__exponent) : "0" (__x)); \
|
|
||||||
__value += 1.0; \
|
|
||||||
__asm __volatile__ \
|
|
||||||
("fscale" \
|
|
||||||
: "=t" (__value) : "0" (__value), "u" (__exponent)); \
|
|
||||||
return __value)
|
|
||||||
|
|
||||||
#define __sincos_code \
|
|
||||||
register long double __cosr; \
|
|
||||||
register long double __sinr; \
|
|
||||||
__asm __volatile__ \
|
|
||||||
("fsincos\n\t" \
|
|
||||||
"fnstsw %%ax\n\t" \
|
|
||||||
"testl $0x400, %%eax\n\t" \
|
|
||||||
"jz 1f\n\t" \
|
|
||||||
"fldpi\n\t" \
|
|
||||||
"fadd %%st(0)\n\t" \
|
|
||||||
"fxch %%st(1)\n\t" \
|
|
||||||
"2: fprem1\n\t" \
|
|
||||||
"fnstsw %%ax\n\t" \
|
|
||||||
"testl $0x400, %%eax\n\t" \
|
|
||||||
"jnz 2b\n\t" \
|
|
||||||
"fstp %%st(1)\n\t" \
|
|
||||||
"fsincos\n\t" \
|
|
||||||
"1:" \
|
|
||||||
: "=t" (__cosr), "=u" (__sinr) : "0" (__x)); \
|
|
||||||
*__sinx = __sinr; \
|
|
||||||
*__cosx = __cosr
|
|
||||||
|
|
||||||
__MATH_INLINE void __sincos (double __x, double *__sinx, double *__cosx);
|
|
||||||
__MATH_INLINE void
|
|
||||||
__sincos (double __x, double *__sinx, double *__cosx)
|
|
||||||
{
|
|
||||||
__sincos_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
__MATH_INLINE void __sincosf (float __x, float *__sinx, float *__cosx);
|
|
||||||
__MATH_INLINE void
|
|
||||||
__sincosf (float __x, float *__sinx, float *__cosx)
|
|
||||||
{
|
|
||||||
__sincos_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
__MATH_INLINE void __sincosl (long double __x, long double *__sinx,
|
|
||||||
long double *__cosx);
|
|
||||||
__MATH_INLINE void
|
|
||||||
__sincosl (long double __x, long double *__sinx, long double *__cosx)
|
|
||||||
{
|
|
||||||
__sincos_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __USE_MISC */
|
#endif /* __USE_MISC */
|
||||||
|
|
||||||
/* Undefine some of the large macros which are not used anymore. */
|
/* Undefine some of the large macros which are not used anymore. */
|
||||||
@ -530,6 +542,7 @@ __sincosl (long double __x, long double *__sinx, long double *__cosx)
|
|||||||
#undef __atan2_code
|
#undef __atan2_code
|
||||||
#undef __sincos_code
|
#undef __sincos_code
|
||||||
|
|
||||||
|
#endif /* Not gcc <= 2.7. */
|
||||||
#endif /* __NO_MATH_INLINES */
|
#endif /* __NO_MATH_INLINES */
|
||||||
#endif /* __GNUC__ */
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ feraiseexcept (int excepts)
|
|||||||
{
|
{
|
||||||
/* One example of a invalid operation is 0.0 / 0.0. */
|
/* One example of a invalid operation is 0.0 / 0.0. */
|
||||||
double d;
|
double d;
|
||||||
__asm__ ("fldz; fdiv %%st, %%st(0); fwait" : "=t" (d));
|
__asm__ __volatile__ ("fldz; fdiv %%st, %%st(0); fwait" : "=t" (d));
|
||||||
(void) &d;
|
(void) &d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,8 @@ feraiseexcept (int excepts)
|
|||||||
if ((FE_DIVBYZERO & excepts) != 0)
|
if ((FE_DIVBYZERO & excepts) != 0)
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
__asm__ ("fldz; fld1; fdivp %%st, %%st(1); fwait" : "=t" (d));
|
__asm__ __volatile__ ("fldz; fld1; fdivp %%st, %%st(1); fwait"
|
||||||
|
: "=t" (d));
|
||||||
(void) &d;
|
(void) &d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,16 +56,16 @@ feraiseexcept (int excepts)
|
|||||||
|
|
||||||
/* Bah, we have to clear selected exceptions. Since there is no
|
/* Bah, we have to clear selected exceptions. Since there is no
|
||||||
`fldsw' instruction we have to do it the hard way. */
|
`fldsw' instruction we have to do it the hard way. */
|
||||||
__asm__ ("fnstenv %0" : "=m" (*&temp));
|
__asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
|
||||||
|
|
||||||
/* Set the relevant bits. */
|
/* Set the relevant bits. */
|
||||||
temp.status_word |= FE_OVERFLOW;
|
temp.status_word |= FE_OVERFLOW;
|
||||||
|
|
||||||
/* Put the new data in effect. */
|
/* Put the new data in effect. */
|
||||||
__asm__ ("fldenv %0" : : "m" (*&temp));
|
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
|
||||||
|
|
||||||
/* And raise the exception. */
|
/* And raise the exception. */
|
||||||
__asm__ ("fwait");
|
__asm__ __volatile__ ("fwait");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next: underflow. */
|
/* Next: underflow. */
|
||||||
@ -76,16 +77,16 @@ feraiseexcept (int excepts)
|
|||||||
|
|
||||||
/* Bah, we have to clear selected exceptions. Since there is no
|
/* Bah, we have to clear selected exceptions. Since there is no
|
||||||
`fldsw' instruction we have to do it the hard way. */
|
`fldsw' instruction we have to do it the hard way. */
|
||||||
__asm__ ("fnstenv %0" : "=m" (*&temp));
|
__asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
|
||||||
|
|
||||||
/* Set the relevant bits. */
|
/* Set the relevant bits. */
|
||||||
temp.status_word |= FE_UNDERFLOW;
|
temp.status_word |= FE_UNDERFLOW;
|
||||||
|
|
||||||
/* Put the new data in effect. */
|
/* Put the new data in effect. */
|
||||||
__asm__ ("fldenv %0" : : "m" (*&temp));
|
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
|
||||||
|
|
||||||
/* And raise the exception. */
|
/* And raise the exception. */
|
||||||
__asm__ ("fwait");
|
__asm__ __volatile__ ("fwait");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Last: inexact. */
|
/* Last: inexact. */
|
||||||
@ -97,15 +98,15 @@ feraiseexcept (int excepts)
|
|||||||
|
|
||||||
/* Bah, we have to clear selected exceptions. Since there is no
|
/* Bah, we have to clear selected exceptions. Since there is no
|
||||||
`fldsw' instruction we have to do it the hard way. */
|
`fldsw' instruction we have to do it the hard way. */
|
||||||
__asm__ ("fnstenv %0" : "=m" (*&temp));
|
__asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
|
||||||
|
|
||||||
/* Set the relevant bits. */
|
/* Set the relevant bits. */
|
||||||
temp.status_word |= FE_INEXACT;
|
temp.status_word |= FE_INEXACT;
|
||||||
|
|
||||||
/* Put the new data in effect. */
|
/* Put the new data in effect. */
|
||||||
__asm__ ("fldenv %0" : : "m" (*&temp));
|
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
|
||||||
|
|
||||||
/* And raise the exception. */
|
/* And raise the exception. */
|
||||||
__asm__ ("fwait");
|
__asm__ __volatile__ ("fwait");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,7 +346,7 @@ static ElfW(Addr) _dl_preferred_address = 1
|
|||||||
|
|
||||||
/* We require the address of the PLT entry returned from fixup, not
|
/* We require the address of the PLT entry returned from fixup, not
|
||||||
the first word of the PLT entry. */
|
the first word of the PLT entry. */
|
||||||
#define ELF_FIXUP_RETURNS_ADDRESS 1
|
#define ELF_FIXUP_RETURN_VALUE(map, result) (&(result))
|
||||||
|
|
||||||
/* Nonzero iff TYPE should not be allowed to resolve to one of
|
/* Nonzero iff TYPE should not be allowed to resolve to one of
|
||||||
the main executable's symbols, as for a COPY reloc. */
|
the main executable's symbols, as for a COPY reloc. */
|
||||||
|
4
sysdeps/sparc/configure
vendored
4
sysdeps/sparc/configure
vendored
@ -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
|
|
@ -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
|
|
@ -62,3 +62,7 @@ typedef double double_t;
|
|||||||
#define INFINITY HUGE_VAL
|
#define INFINITY HUGE_VAL
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* The values returned by `ilogb' for 0 and NaN respectively. */
|
||||||
|
#define FP_ILOGB0 0x80000001
|
||||||
|
#define FP_ILOGBNAN 0x7fffffff
|
||||||
|
@ -20,14 +20,16 @@
|
|||||||
#include <fenv.h>
|
#include <fenv.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
static void
|
|
||||||
ignore_me(double foo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
feraiseexcept (int excepts)
|
feraiseexcept (int excepts)
|
||||||
{
|
{
|
||||||
|
static volatile double sink;
|
||||||
|
static const struct {
|
||||||
|
double zero, one, max, min, sixteen, pi;
|
||||||
|
} c = {
|
||||||
|
0.0, 1.0, DBL_MAX, DBL_MIN, 16.0, M_PI
|
||||||
|
};
|
||||||
|
|
||||||
/* Raise exceptions represented by EXPECTS. But we must raise only
|
/* Raise exceptions represented by EXPECTS. But we must raise only
|
||||||
one signal at a time. It is important the if the overflow/underflow
|
one signal at a time. It is important the if the overflow/underflow
|
||||||
exception and the inexact exception are given at the same time,
|
exception and the inexact exception are given at the same time,
|
||||||
@ -37,30 +39,30 @@ feraiseexcept (int excepts)
|
|||||||
if ((FE_INVALID & excepts) != 0)
|
if ((FE_INVALID & excepts) != 0)
|
||||||
{
|
{
|
||||||
/* One example of a invalid operation is 0/0. */
|
/* One example of a invalid operation is 0/0. */
|
||||||
ignore_me (0.0 / 0.0);
|
sink = c.zero / c.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next: division by zero. */
|
/* Next: division by zero. */
|
||||||
if ((FE_DIVBYZERO & excepts) != 0)
|
if ((FE_DIVBYZERO & excepts) != 0)
|
||||||
{
|
{
|
||||||
ignore_me (1.0 / 0.0);
|
sink = c.one / c.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next: overflow. */
|
/* Next: overflow. */
|
||||||
if ((FE_OVERFLOW & excepts) != 0)
|
if ((FE_OVERFLOW & excepts) != 0)
|
||||||
{
|
{
|
||||||
ignore_me (LDBL_MAX * LDBL_MAX);
|
sink = c.max * c.max;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next: underflow. */
|
/* Next: underflow. */
|
||||||
if ((FE_UNDERFLOW & excepts) != 0)
|
if ((FE_UNDERFLOW & excepts) != 0)
|
||||||
{
|
{
|
||||||
ignore_me (LDBL_MIN / 16.0);
|
sink = c.min / c.sixteen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Last: inexact. */
|
/* Last: inexact. */
|
||||||
if ((FE_INEXACT & excepts) != 0)
|
if ((FE_INEXACT & excepts) != 0)
|
||||||
{
|
{
|
||||||
ignore_me (1.0 / M_PI);
|
sink = c.one / c.pi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ divrem := sdiv udiv rem urem
|
|||||||
+divrem-S-rem := true
|
+divrem-S-rem := true
|
||||||
+divrem-S-udiv := false
|
+divrem-S-udiv := false
|
||||||
+divrem-S-urem := false
|
+divrem-S-urem := false
|
||||||
$(divrem:%=$(sysdep_dir)/sparc/%.S): $(sysdep_dir)/sparc/divrem.m4
|
$(divrem:%=$(sysdep_dir)/sparc/sparc32/%.S): $(sysdep_dir)/sparc/sparc32/divrem.m4
|
||||||
(echo "define(NAME,\`.$(+divrem-NAME)')\
|
(echo "define(NAME,\`.$(+divrem-NAME)')\
|
||||||
define(OP,\`$(+divrem-OP-$(+divrem-NAME))')\
|
define(OP,\`$(+divrem-OP-$(+divrem-NAME))')\
|
||||||
define(S,\`$(+divrem-S-$(+divrem-NAME))')\
|
define(S,\`$(+divrem-S-$(+divrem-NAME))')\
|
||||||
@ -48,4 +48,4 @@ $(divrem:%=$(sysdep_dir)/sparc/%.S): $(sysdep_dir)/sparc/divrem.m4
|
|||||||
mv -f $@-tmp $@
|
mv -f $@-tmp $@
|
||||||
test ! -d CVS || cvs commit -m'Regenerated from $<' $@
|
test ! -d CVS || cvs commit -m'Regenerated from $<' $@
|
||||||
|
|
||||||
sysdep-realclean := $(sysdep-realclean) $(divrem:%=sysdeps/sparc/%.S)
|
sysdep-realclean := $(sysdep-realclean) $(divrem:%=sysdeps/sparc/sparc32/%.S)
|
||||||
|
@ -22,38 +22,43 @@
|
|||||||
#include <bits/setjmp.h>
|
#include <bits/setjmp.h>
|
||||||
#define ENV(reg) [%g1 + (reg * 4)]
|
#define ENV(reg) [%g1 + (reg * 4)]
|
||||||
|
|
||||||
ENTRY (__longjmp)
|
ENTRY(__longjmp)
|
||||||
/* Store our arguments in global registers so we can still
|
/* Store our arguments in global registers so we can still
|
||||||
use them while unwinding frames and their register windows. */
|
use them while unwinding frames and their register windows. */
|
||||||
mov %o0, %g1 /* ENV in %g1 */
|
mov %o0, %g1 /* ENV in %g1 */
|
||||||
orcc %o1, %g0, %g6 /* VAL in %g6 */
|
orcc %o1, %g0, %g2 /* VAL in %g2 */
|
||||||
be,a 0f /* Branch if zero; else skip delay slot. */
|
be,a 0f /* Branch if zero; else skip delay slot. */
|
||||||
mov 1, %g6 /* Delay slot only hit if zero: VAL = 1. */
|
mov 1, %g2 /* Delay slot only hit if zero: VAL = 1. */
|
||||||
0:
|
0:
|
||||||
|
/* Cache target FP in register %g3. */
|
||||||
/* Cache target FP in register %g7. */
|
ld ENV(JB_FP), %g3
|
||||||
ld ENV (JB_FP), %g7
|
|
||||||
|
|
||||||
/* Now we will loop, unwinding the register windows up the stack
|
/* Now we will loop, unwinding the register windows up the stack
|
||||||
until the restored %fp value matches the target value in %g7. */
|
until the restored %fp value matches the target value in %g3. */
|
||||||
|
|
||||||
loop: cmp %fp, %g7 /* Have we reached the target frame? */
|
LOC(loop):
|
||||||
bl,a loop /* Loop while current fp is below target. */
|
cmp %fp, %g3 /* Have we reached the target frame? */
|
||||||
|
bl,a LOC(loop) /* Loop while current fp is below target. */
|
||||||
restore /* Unwind register window in delay slot. */
|
restore /* Unwind register window in delay slot. */
|
||||||
be,a found /* Better have hit it exactly. */
|
be,a LOC(found) /* Better have hit it exactly. */
|
||||||
ld ENV (JB_SP), %o0 /* Delay slot: extract target SP. */
|
ld ENV(JB_SP), %o0 /* Delay slot: extract target SP. */
|
||||||
|
|
||||||
bogus: /* Get here only if the jmp_buf or stack is clobbered. */
|
LOC(bogus):
|
||||||
call C_SYMBOL_NAME (abort)
|
/* Get here only if the jmp_buf or stack is clobbered. */
|
||||||
nop
|
call C_SYMBOL_NAME(abort)
|
||||||
|
nop
|
||||||
unimp 0
|
unimp 0
|
||||||
|
|
||||||
found: /* We have unwound register windows so %fp matches the target. */
|
LOC(found):
|
||||||
|
/* We have unwound register windows so %fp matches the target. */
|
||||||
cmp %o0, %sp /* Check jmp_buf SP vs register window. */
|
cmp %o0, %sp /* Check jmp_buf SP vs register window. */
|
||||||
bge,a sp_ok /* Saved must not be deeper than register. */
|
bge,a LOC(sp_ok) /* Saved must not be deeper than register. */
|
||||||
mov %o0, %sp /* OK, install new SP. */
|
mov %o0, %sp /* OK, install new SP. */
|
||||||
b,a bogus /* Bogus, we lose. */
|
b,a LOC(bogus) /* Bogus, we lose. */
|
||||||
|
|
||||||
sp_ok: ld ENV (JB_PC), %o0 /* Extract target return PC. */
|
LOC(sp_ok):
|
||||||
|
ld ENV(JB_PC), %o0 /* Extract target return PC. */
|
||||||
jmp %o0 + 8 /* Return there. */
|
jmp %o0 + 8 /* Return there. */
|
||||||
mov %g6, %o0 /* Delay slot: set return value. */
|
mov %g2, %o0 /* Delay slot: set return value. */
|
||||||
|
|
||||||
|
END(__longjmp)
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
|
! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
|
||||||
! sum in a third limb vector.
|
! sum in a third limb vector.
|
||||||
|
!
|
||||||
! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
!
|
||||||
! This file is part of the GNU MP Library.
|
! This file is part of the GNU MP Library.
|
||||||
|
!
|
||||||
! The GNU MP Library is free software; you can redistribute it and/or modify
|
! The GNU MP Library is free software; you can redistribute it and/or modify
|
||||||
! it under the terms of the GNU Library General Public License as published by
|
! it under the terms of the GNU Library General Public License as published by
|
||||||
! the Free Software Foundation; either version 2 of the License, or (at your
|
! the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
! option) any later version.
|
! option) any later version.
|
||||||
|
!
|
||||||
! The GNU MP Library is distributed in the hope that it will be useful, but
|
! The GNU MP Library is distributed in the hope that it will be useful, but
|
||||||
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
! License for more details.
|
! License for more details.
|
||||||
|
!
|
||||||
! You should have received a copy of the GNU Library General Public License
|
! You should have received a copy of the GNU Library General Public License
|
||||||
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||||
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
@ -22,205 +22,217 @@
|
|||||||
|
|
||||||
|
|
||||||
! INPUT PARAMETERS
|
! INPUT PARAMETERS
|
||||||
#define res_ptr %o0
|
#define RES_PTR %o0
|
||||||
#define s1_ptr %o1
|
#define S1_PTR %o1
|
||||||
#define s2_ptr %o2
|
#define S2_PTR %o2
|
||||||
#define size %o3
|
#define SIZE %o3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_add_n)
|
||||||
.align 4
|
xor S2_PTR,RES_PTR,%g1
|
||||||
.global C_SYMBOL_NAME(__mpn_add_n)
|
|
||||||
C_SYMBOL_NAME(__mpn_add_n):
|
|
||||||
xor s2_ptr,res_ptr,%g1
|
|
||||||
andcc %g1,4,%g0
|
andcc %g1,4,%g0
|
||||||
bne L1 ! branch if alignment differs
|
bne LOC(1) ! branch if alignment differs
|
||||||
nop
|
nop
|
||||||
! ** V1a **
|
! ** V1a **
|
||||||
L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
|
LOC(0): andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
|
||||||
be L_v1 ! if no, branch
|
be LOC(v1) ! if no, branch
|
||||||
nop
|
nop
|
||||||
/* Add least significant limb separately to align res_ptr and s2_ptr */
|
/* Add least significant limb separately to align RES_PTR and S2_PTR */
|
||||||
ld [s1_ptr],%g4
|
ld [S1_PTR],%g4
|
||||||
add s1_ptr,4,s1_ptr
|
add S1_PTR,4,S1_PTR
|
||||||
ld [s2_ptr],%g2
|
ld [S2_PTR],%g2
|
||||||
add s2_ptr,4,s2_ptr
|
add S2_PTR,4,S2_PTR
|
||||||
add size,-1,size
|
add SIZE,-1,SIZE
|
||||||
addcc %g4,%g2,%o4
|
addcc %g4,%g2,%o4
|
||||||
st %o4,[res_ptr]
|
st %o4,[RES_PTR]
|
||||||
add res_ptr,4,res_ptr
|
add RES_PTR,4,RES_PTR
|
||||||
L_v1: addx %g0,%g0,%o4 ! save cy in register
|
LOC(v1):
|
||||||
cmp size,2 ! if size < 2 ...
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
bl Lend2 ! ... branch to tail code
|
cmp SIZE,2 ! if SIZE < 2 ...
|
||||||
|
bl LOC(end2) ! ... branch to tail code
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
|
|
||||||
ld [s1_ptr+0],%g4
|
ld [S1_PTR+0],%g4
|
||||||
addcc size,-10,size
|
addcc SIZE,-10,SIZE
|
||||||
ld [s1_ptr+4],%g1
|
ld [S1_PTR+4],%g1
|
||||||
ldd [s2_ptr+0],%g2
|
ldd [S2_PTR+0],%g2
|
||||||
blt Lfin1
|
blt LOC(fin1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||||
Loop1: addxcc %g4,%g2,%o4
|
LOC(loop1):
|
||||||
ld [s1_ptr+8],%g4
|
|
||||||
addxcc %g1,%g3,%o5
|
|
||||||
ld [s1_ptr+12],%g1
|
|
||||||
ldd [s2_ptr+8],%g2
|
|
||||||
std %o4,[res_ptr+0]
|
|
||||||
addxcc %g4,%g2,%o4
|
addxcc %g4,%g2,%o4
|
||||||
ld [s1_ptr+16],%g4
|
ld [S1_PTR+8],%g4
|
||||||
addxcc %g1,%g3,%o5
|
addxcc %g1,%g3,%o5
|
||||||
ld [s1_ptr+20],%g1
|
ld [S1_PTR+12],%g1
|
||||||
ldd [s2_ptr+16],%g2
|
ldd [S2_PTR+8],%g2
|
||||||
std %o4,[res_ptr+8]
|
std %o4,[RES_PTR+0]
|
||||||
addxcc %g4,%g2,%o4
|
addxcc %g4,%g2,%o4
|
||||||
ld [s1_ptr+24],%g4
|
ld [S1_PTR+16],%g4
|
||||||
addxcc %g1,%g3,%o5
|
addxcc %g1,%g3,%o5
|
||||||
ld [s1_ptr+28],%g1
|
ld [S1_PTR+20],%g1
|
||||||
ldd [s2_ptr+24],%g2
|
ldd [S2_PTR+16],%g2
|
||||||
std %o4,[res_ptr+16]
|
std %o4,[RES_PTR+8]
|
||||||
addxcc %g4,%g2,%o4
|
addxcc %g4,%g2,%o4
|
||||||
ld [s1_ptr+32],%g4
|
ld [S1_PTR+24],%g4
|
||||||
addxcc %g1,%g3,%o5
|
addxcc %g1,%g3,%o5
|
||||||
ld [s1_ptr+36],%g1
|
ld [S1_PTR+28],%g1
|
||||||
ldd [s2_ptr+32],%g2
|
ldd [S2_PTR+24],%g2
|
||||||
std %o4,[res_ptr+24]
|
std %o4,[RES_PTR+16]
|
||||||
|
addxcc %g4,%g2,%o4
|
||||||
|
ld [S1_PTR+32],%g4
|
||||||
|
addxcc %g1,%g3,%o5
|
||||||
|
ld [S1_PTR+36],%g1
|
||||||
|
ldd [S2_PTR+32],%g2
|
||||||
|
std %o4,[RES_PTR+24]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-8,size
|
addcc SIZE,-8,SIZE
|
||||||
add s1_ptr,32,s1_ptr
|
add S1_PTR,32,S1_PTR
|
||||||
add s2_ptr,32,s2_ptr
|
add S2_PTR,32,S2_PTR
|
||||||
add res_ptr,32,res_ptr
|
add RES_PTR,32,RES_PTR
|
||||||
bge Loop1
|
bge LOC(loop1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
|
|
||||||
Lfin1: addcc size,8-2,size
|
LOC(fin1):
|
||||||
blt Lend1
|
addcc SIZE,8-2,SIZE
|
||||||
|
blt LOC(end1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add blocks of 2 limbs until less than 2 limbs remain */
|
/* Add blocks of 2 limbs until less than 2 limbs remain */
|
||||||
Loope1: addxcc %g4,%g2,%o4
|
LOC(loope1):
|
||||||
ld [s1_ptr+8],%g4
|
addxcc %g4,%g2,%o4
|
||||||
|
ld [S1_PTR+8],%g4
|
||||||
addxcc %g1,%g3,%o5
|
addxcc %g1,%g3,%o5
|
||||||
ld [s1_ptr+12],%g1
|
ld [S1_PTR+12],%g1
|
||||||
ldd [s2_ptr+8],%g2
|
ldd [S2_PTR+8],%g2
|
||||||
std %o4,[res_ptr+0]
|
std %o4,[RES_PTR+0]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-2,size
|
addcc SIZE,-2,SIZE
|
||||||
add s1_ptr,8,s1_ptr
|
add S1_PTR,8,S1_PTR
|
||||||
add s2_ptr,8,s2_ptr
|
add S2_PTR,8,S2_PTR
|
||||||
add res_ptr,8,res_ptr
|
add RES_PTR,8,RES_PTR
|
||||||
bge Loope1
|
bge LOC(loope1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
Lend1: addxcc %g4,%g2,%o4
|
LOC(end1):
|
||||||
|
addxcc %g4,%g2,%o4
|
||||||
addxcc %g1,%g3,%o5
|
addxcc %g1,%g3,%o5
|
||||||
std %o4,[res_ptr+0]
|
std %o4,[RES_PTR+0]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
|
|
||||||
andcc size,1,%g0
|
andcc SIZE,1,%g0
|
||||||
be Lret1
|
be LOC(ret1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add last limb */
|
/* Add last limb */
|
||||||
ld [s1_ptr+8],%g4
|
ld [S1_PTR+8],%g4
|
||||||
ld [s2_ptr+8],%g2
|
ld [S2_PTR+8],%g2
|
||||||
addxcc %g4,%g2,%o4
|
addxcc %g4,%g2,%o4
|
||||||
st %o4,[res_ptr+8]
|
st %o4,[RES_PTR+8]
|
||||||
|
|
||||||
Lret1: retl
|
LOC(ret1):
|
||||||
|
retl
|
||||||
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
||||||
|
|
||||||
L1: xor s1_ptr,res_ptr,%g1
|
LOC(1): xor S1_PTR,RES_PTR,%g1
|
||||||
andcc %g1,4,%g0
|
andcc %g1,4,%g0
|
||||||
bne L2
|
bne LOC(2)
|
||||||
nop
|
nop
|
||||||
! ** V1b **
|
! ** V1b **
|
||||||
mov s2_ptr,%g1
|
mov S2_PTR,%g1
|
||||||
mov s1_ptr,s2_ptr
|
mov S1_PTR,S2_PTR
|
||||||
b L0
|
b LOC(0)
|
||||||
mov %g1,s1_ptr
|
mov %g1,S1_PTR
|
||||||
|
|
||||||
! ** V2 **
|
! ** V2 **
|
||||||
/* If we come here, the alignment of s1_ptr and res_ptr as well as the
|
/* If we come here, the alignment of S1_PTR and RES_PTR as well as the
|
||||||
alignment of s2_ptr and res_ptr differ. Since there are only two ways
|
alignment of S2_PTR and RES_PTR differ. Since there are only two ways
|
||||||
things can be aligned (that we care about) we now know that the alignment
|
things can be aligned (that we care about) we now know that the alignment
|
||||||
of s1_ptr and s2_ptr are the same. */
|
of S1_PTR and S2_PTR are the same. */
|
||||||
|
|
||||||
L2: cmp size,1
|
LOC(2): cmp SIZE,1
|
||||||
be Ljone
|
be LOC(jone)
|
||||||
nop
|
nop
|
||||||
andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
|
andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
|
||||||
be L_v2 ! if no, branch
|
be LOC(v2) ! if no, branch
|
||||||
nop
|
nop
|
||||||
/* Add least significant limb separately to align s1_ptr and s2_ptr */
|
/* Add least significant limb separately to align S1_PTR and S2_PTR */
|
||||||
ld [s1_ptr],%g4
|
ld [S1_PTR],%g4
|
||||||
add s1_ptr,4,s1_ptr
|
add S1_PTR,4,S1_PTR
|
||||||
ld [s2_ptr],%g2
|
ld [S2_PTR],%g2
|
||||||
add s2_ptr,4,s2_ptr
|
add S2_PTR,4,S2_PTR
|
||||||
add size,-1,size
|
add SIZE,-1,SIZE
|
||||||
addcc %g4,%g2,%o4
|
addcc %g4,%g2,%o4
|
||||||
st %o4,[res_ptr]
|
st %o4,[RES_PTR]
|
||||||
add res_ptr,4,res_ptr
|
add RES_PTR,4,RES_PTR
|
||||||
|
|
||||||
L_v2: addx %g0,%g0,%o4 ! save cy in register
|
LOC(v2):
|
||||||
addcc size,-8,size
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
blt Lfin2
|
addcc SIZE,-8,SIZE
|
||||||
|
blt LOC(fin2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||||
Loop2: ldd [s1_ptr+0],%g2
|
LOC(loop2):
|
||||||
ldd [s2_ptr+0],%o4
|
ldd [S1_PTR+0],%g2
|
||||||
|
ldd [S2_PTR+0],%o4
|
||||||
addxcc %g2,%o4,%g2
|
addxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+0]
|
st %g2,[RES_PTR+0]
|
||||||
addxcc %g3,%o5,%g3
|
addxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+4]
|
st %g3,[RES_PTR+4]
|
||||||
ldd [s1_ptr+8],%g2
|
ldd [S1_PTR+8],%g2
|
||||||
ldd [s2_ptr+8],%o4
|
ldd [S2_PTR+8],%o4
|
||||||
addxcc %g2,%o4,%g2
|
addxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+8]
|
st %g2,[RES_PTR+8]
|
||||||
addxcc %g3,%o5,%g3
|
addxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+12]
|
st %g3,[RES_PTR+12]
|
||||||
ldd [s1_ptr+16],%g2
|
ldd [S1_PTR+16],%g2
|
||||||
ldd [s2_ptr+16],%o4
|
ldd [S2_PTR+16],%o4
|
||||||
addxcc %g2,%o4,%g2
|
addxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+16]
|
st %g2,[RES_PTR+16]
|
||||||
addxcc %g3,%o5,%g3
|
addxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+20]
|
st %g3,[RES_PTR+20]
|
||||||
ldd [s1_ptr+24],%g2
|
ldd [S1_PTR+24],%g2
|
||||||
ldd [s2_ptr+24],%o4
|
ldd [S2_PTR+24],%o4
|
||||||
addxcc %g2,%o4,%g2
|
addxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+24]
|
st %g2,[RES_PTR+24]
|
||||||
addxcc %g3,%o5,%g3
|
addxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+28]
|
st %g3,[RES_PTR+28]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-8,size
|
addcc SIZE,-8,SIZE
|
||||||
add s1_ptr,32,s1_ptr
|
add S1_PTR,32,S1_PTR
|
||||||
add s2_ptr,32,s2_ptr
|
add S2_PTR,32,S2_PTR
|
||||||
add res_ptr,32,res_ptr
|
add RES_PTR,32,RES_PTR
|
||||||
bge Loop2
|
bge LOC(loop2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
|
|
||||||
Lfin2: addcc size,8-2,size
|
LOC(fin2):
|
||||||
blt Lend2
|
addcc SIZE,8-2,SIZE
|
||||||
|
blt LOC(end2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
Loope2: ldd [s1_ptr+0],%g2
|
LOC(loope2):
|
||||||
ldd [s2_ptr+0],%o4
|
ldd [S1_PTR+0],%g2
|
||||||
|
ldd [S2_PTR+0],%o4
|
||||||
addxcc %g2,%o4,%g2
|
addxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+0]
|
st %g2,[RES_PTR+0]
|
||||||
addxcc %g3,%o5,%g3
|
addxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+4]
|
st %g3,[RES_PTR+4]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-2,size
|
addcc SIZE,-2,SIZE
|
||||||
add s1_ptr,8,s1_ptr
|
add S1_PTR,8,S1_PTR
|
||||||
add s2_ptr,8,s2_ptr
|
add S2_PTR,8,S2_PTR
|
||||||
add res_ptr,8,res_ptr
|
add RES_PTR,8,RES_PTR
|
||||||
bge Loope2
|
bge LOC(loope2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
Lend2: andcc size,1,%g0
|
LOC(end2):
|
||||||
be Lret2
|
andcc SIZE,1,%g0
|
||||||
|
be LOC(ret2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add last limb */
|
/* Add last limb */
|
||||||
Ljone: ld [s1_ptr],%g4
|
LOC(jone):
|
||||||
ld [s2_ptr],%g2
|
ld [S1_PTR],%g4
|
||||||
|
ld [S2_PTR],%g2
|
||||||
addxcc %g4,%g2,%o4
|
addxcc %g4,%g2,%o4
|
||||||
st %o4,[res_ptr]
|
st %o4,[RES_PTR]
|
||||||
|
|
||||||
Lret2: retl
|
LOC(ret2):
|
||||||
|
retl
|
||||||
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
||||||
|
|
||||||
|
END(__mpn_add_n)
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add
|
! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add
|
||||||
! the result to a second limb vector.
|
! the result to a second limb vector.
|
||||||
|
!
|
||||||
! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
|
! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
|
||||||
|
!
|
||||||
! This file is part of the GNU MP Library.
|
! This file is part of the GNU MP Library.
|
||||||
|
!
|
||||||
! The GNU MP Library is free software; you can redistribute it and/or modify
|
! The GNU MP Library is free software; you can redistribute it and/or modify
|
||||||
! it under the terms of the GNU Library General Public License as published by
|
! it under the terms of the GNU Library General Public License as published by
|
||||||
! the Free Software Foundation; either version 2 of the License, or (at your
|
! the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
! option) any later version.
|
! option) any later version.
|
||||||
|
!
|
||||||
! The GNU MP Library is distributed in the hope that it will be useful, but
|
! The GNU MP Library is distributed in the hope that it will be useful, but
|
||||||
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
! License for more details.
|
! License for more details.
|
||||||
|
!
|
||||||
! You should have received a copy of the GNU Library General Public License
|
! You should have received a copy of the GNU Library General Public License
|
||||||
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||||
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
@ -22,17 +22,14 @@
|
|||||||
|
|
||||||
|
|
||||||
! INPUT PARAMETERS
|
! INPUT PARAMETERS
|
||||||
! res_ptr o0
|
! RES_PTR o0
|
||||||
! s1_ptr o1
|
! S1_PTR o1
|
||||||
! size o2
|
! SIZE o2
|
||||||
! s2_limb o3
|
! S2_LIMB o3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_addmul_1)
|
||||||
.align 4
|
|
||||||
.global C_SYMBOL_NAME(__mpn_addmul_1)
|
|
||||||
C_SYMBOL_NAME(__mpn_addmul_1):
|
|
||||||
! Make S1_PTR and RES_PTR point at the end of their blocks
|
! Make S1_PTR and RES_PTR point at the end of their blocks
|
||||||
! and put (- 4 x SIZE) in index/loop counter.
|
! and put (- 4 x SIZE) in index/loop counter.
|
||||||
sll %o2,2,%o2
|
sll %o2,2,%o2
|
||||||
@ -41,19 +38,19 @@ C_SYMBOL_NAME(__mpn_addmul_1):
|
|||||||
sub %g0,%o2,%o2
|
sub %g0,%o2,%o2
|
||||||
|
|
||||||
cmp %o3,0xfff
|
cmp %o3,0xfff
|
||||||
bgu Large
|
bgu LOC(large)
|
||||||
nop
|
nop
|
||||||
|
|
||||||
ld [%o1+%o2],%o5
|
ld [%o1+%o2],%o5
|
||||||
mov 0,%o0
|
mov 0,%o0
|
||||||
b L0
|
b LOC(0)
|
||||||
add %o4,-4,%o4
|
add %o4,-4,%o4
|
||||||
Loop0:
|
LOC(loop0):
|
||||||
addcc %o5,%g1,%g1
|
addcc %o5,%g1,%g1
|
||||||
ld [%o1+%o2],%o5
|
ld [%o1+%o2],%o5
|
||||||
addx %o0,%g0,%o0
|
addx %o0,%g0,%o0
|
||||||
st %g1,[%o4+%o2]
|
st %g1,[%o4+%o2]
|
||||||
L0: wr %g0,%o3,%y
|
LOC(0): wr %g0,%o3,%y
|
||||||
sra %o5,31,%g2
|
sra %o5,31,%g2
|
||||||
and %o3,%g2,%g2
|
and %o3,%g2,%g2
|
||||||
andcc %g1,0,%g1
|
andcc %g1,0,%g1
|
||||||
@ -79,7 +76,7 @@ L0: wr %g0,%o3,%y
|
|||||||
addcc %g1,%o0,%g1
|
addcc %g1,%o0,%g1
|
||||||
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
|
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
|
||||||
addcc %o2,4,%o2 ! loop counter
|
addcc %o2,4,%o2 ! loop counter
|
||||||
bne Loop0
|
bne LOC(loop0)
|
||||||
ld [%o4+%o2],%o5
|
ld [%o4+%o2],%o5
|
||||||
|
|
||||||
addcc %o5,%g1,%g1
|
addcc %o5,%g1,%g1
|
||||||
@ -88,17 +85,18 @@ L0: wr %g0,%o3,%y
|
|||||||
st %g1,[%o4+%o2]
|
st %g1,[%o4+%o2]
|
||||||
|
|
||||||
|
|
||||||
Large: ld [%o1+%o2],%o5
|
LOC(large):
|
||||||
|
ld [%o1+%o2],%o5
|
||||||
mov 0,%o0
|
mov 0,%o0
|
||||||
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
|
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
|
||||||
b L1
|
b LOC(1)
|
||||||
add %o4,-4,%o4
|
add %o4,-4,%o4
|
||||||
Loop:
|
LOC(loop):
|
||||||
addcc %o5,%g3,%g3
|
addcc %o5,%g3,%g3
|
||||||
ld [%o1+%o2],%o5
|
ld [%o1+%o2],%o5
|
||||||
addx %o0,%g0,%o0
|
addx %o0,%g0,%o0
|
||||||
st %g3,[%o4+%o2]
|
st %g3,[%o4+%o2]
|
||||||
L1: wr %g0,%o5,%y
|
LOC(1): wr %g0,%o5,%y
|
||||||
and %o5,%g4,%g2
|
and %o5,%g4,%g2
|
||||||
andcc %g0,%g0,%g1
|
andcc %g0,%g0,%g1
|
||||||
mulscc %g1,%o3,%g1
|
mulscc %g1,%o3,%g1
|
||||||
@ -138,10 +136,12 @@ L1: wr %g0,%o5,%y
|
|||||||
addcc %g3,%o0,%g3
|
addcc %g3,%o0,%g3
|
||||||
addx %g2,%g1,%o0
|
addx %g2,%g1,%o0
|
||||||
addcc %o2,4,%o2
|
addcc %o2,4,%o2
|
||||||
bne Loop
|
bne LOC(loop)
|
||||||
ld [%o4+%o2],%o5
|
ld [%o4+%o2],%o5
|
||||||
|
|
||||||
addcc %o5,%g3,%g3
|
addcc %o5,%g3,%g3
|
||||||
addx %o0,%g0,%o0
|
addx %o0,%g0,%o0
|
||||||
retl
|
retl
|
||||||
st %g3,[%o4+%o2]
|
st %g3,[%o4+%o2]
|
||||||
|
|
||||||
|
END(__mpn_addmul_1)
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
Boston, MA 02111-1307, USA. */
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
/* Code produced by Sun's C compiler calls this function with two extra
|
/* Code produced by Sun's C compiler calls this function with two extra
|
||||||
arguments which it makes relocatable symbols but seem always to be
|
arguments which it makes relocatable symbols but seem always to be
|
||||||
@ -30,3 +30,4 @@ ENTRY (__builtin_alloca)
|
|||||||
sub %sp, %o0, %sp /* Push some stack space. */
|
sub %sp, %o0, %sp /* Push some stack space. */
|
||||||
retl /* Return; the returned buffer leaves 96 */
|
retl /* Return; the returned buffer leaves 96 */
|
||||||
add %sp, 96, %o0 /* bytes of register save area at the top. */
|
add %sp, 96, %o0 /* bytes of register save area at the top. */
|
||||||
|
END (__builtin_alloca)
|
||||||
|
@ -1,40 +1 @@
|
|||||||
/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. Sparc version.
|
/* _setjmp is in setjmp.S */
|
||||||
Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of the
|
|
||||||
License, or (at your option) any later version.
|
|
||||||
|
|
||||||
The GNU C Library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include <sysdep.h>
|
|
||||||
|
|
||||||
ENTRY (_setjmp)
|
|
||||||
|
|
||||||
#ifdef PIC
|
|
||||||
save %sp, -64, %sp
|
|
||||||
1: call 2f
|
|
||||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %g1
|
|
||||||
2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %g1
|
|
||||||
add %g1, %o7, %g1
|
|
||||||
sethi %hi(C_SYMBOL_NAME(__sigsetjmp)), %g2
|
|
||||||
restore
|
|
||||||
or %g2, %lo(C_SYMBOL_NAME(__sigsetjmp)), %g2
|
|
||||||
ld [%g1+%g2], %g1
|
|
||||||
#else
|
|
||||||
sethi %hi(C_SYMBOL_NAME(__sigsetjmp)), %g1
|
|
||||||
or %g1, %lo(C_SYMBOL_NAME(__sigsetjmp)), %g1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jmp %g1
|
|
||||||
mov %g0, %o1 /* Pass second argument of zero. */
|
|
||||||
|
@ -1,40 +1 @@
|
|||||||
/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. Sparc version.
|
/* setjmp is in setjmp.S */
|
||||||
Copyright (C) 1994, 1997 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of the
|
|
||||||
License, or (at your option) any later version.
|
|
||||||
|
|
||||||
The GNU C Library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include <sysdep.h>
|
|
||||||
|
|
||||||
ENTRY (setjmp)
|
|
||||||
|
|
||||||
#ifdef PIC
|
|
||||||
save %sp, -64, %sp
|
|
||||||
1: call 2f
|
|
||||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %g1
|
|
||||||
2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %g1
|
|
||||||
add %g1, %o7, %g1
|
|
||||||
sethi %hi(C_SYMBOL_NAME(__sigsetjmp)), %g2
|
|
||||||
restore
|
|
||||||
or %g2, %lo(C_SYMBOL_NAME(__sigsetjmp)), %g2
|
|
||||||
ld [%g1+%g2], %g1
|
|
||||||
#else
|
|
||||||
sethi %hi(C_SYMBOL_NAME(__sigsetjmp)), %g1
|
|
||||||
or %g1, %lo(C_SYMBOL_NAME(__sigsetjmp)), %g1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jmp %g1
|
|
||||||
mov 1, %o1 /* Pass second argument of one. */
|
|
||||||
|
@ -47,8 +47,8 @@ define(V, `%o5')dnl
|
|||||||
dnl
|
dnl
|
||||||
dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d
|
dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d
|
||||||
define(T, `%g1')dnl
|
define(T, `%g1')dnl
|
||||||
define(SC, `%g7')dnl
|
define(SC, `%g2')dnl
|
||||||
ifelse(S, `true', `define(SIGN, `%g6')')dnl
|
ifelse(S, `true', `define(SIGN, `%g3')')dnl
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl This is the recursive definition for developing quotient digits.
|
dnl This is the recursive definition for developing quotient digits.
|
||||||
@ -65,7 +65,7 @@ dnl modified to reflect the output R.
|
|||||||
dnl
|
dnl
|
||||||
define(DEVELOP_QUOTIENT_BITS,
|
define(DEVELOP_QUOTIENT_BITS,
|
||||||
` ! depth $1, accumulated bits $2
|
` ! depth $1, accumulated bits $2
|
||||||
bl L.$1.eval(2**N+$2)
|
bl LOC($1.eval(2**N+$2))
|
||||||
srl V,1,V
|
srl V,1,V
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc R,V,R
|
subcc R,V,R
|
||||||
@ -73,7 +73,7 @@ define(DEVELOP_QUOTIENT_BITS,
|
|||||||
` b 9f
|
` b 9f
|
||||||
add Q, ($2*2+1), Q
|
add Q, ($2*2+1), Q
|
||||||
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')')
|
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')')
|
||||||
L.$1.eval(2**N+$2):
|
LOC($1.eval(2**N+$2)):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc R,V,R
|
addcc R,V,R
|
||||||
ifelse($1, N,
|
ifelse($1, N,
|
||||||
@ -82,18 +82,10 @@ L.$1.eval(2**N+$2):
|
|||||||
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')')
|
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')')
|
||||||
ifelse($1, 1, `9:')')dnl
|
ifelse($1, 1, `9:')')dnl
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
#ifdef __linux__
|
|
||||||
#include <asm/traps.h>
|
|
||||||
#else
|
|
||||||
#ifdef __svr4__
|
|
||||||
#include <sys/trap.h>
|
#include <sys/trap.h>
|
||||||
#else
|
|
||||||
#include <machine/trap.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FUNC(NAME)
|
ENTRY(NAME)
|
||||||
ifelse(S, `true',
|
ifelse(S, `true',
|
||||||
` ! compute sign of result; if neither is negative, no problem
|
` ! compute sign of result; if neither is negative, no problem
|
||||||
orcc divisor, dividend, %g0 ! either negative?
|
orcc divisor, dividend, %g0 ! either negative?
|
||||||
@ -124,11 +116,11 @@ ifelse(OP, `div',
|
|||||||
|
|
||||||
1:
|
1:
|
||||||
cmp R, V ! if divisor exceeds dividend, done
|
cmp R, V ! if divisor exceeds dividend, done
|
||||||
blu Lgot_result ! (and algorithm fails otherwise)
|
blu LOC(got_result) ! (and algorithm fails otherwise)
|
||||||
clr Q
|
clr Q
|
||||||
sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T
|
sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T
|
||||||
cmp R, T
|
cmp R, T
|
||||||
blu Lnot_really_big
|
blu LOC(not_really_big)
|
||||||
clr ITER
|
clr ITER
|
||||||
|
|
||||||
! `Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
! `Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
||||||
@ -146,7 +138,7 @@ ifelse(OP, `div',
|
|||||||
|
|
||||||
! Now compute SC.
|
! Now compute SC.
|
||||||
2: addcc V, V, V
|
2: addcc V, V, V
|
||||||
bcc Lnot_too_big
|
bcc LOC(not_too_big)
|
||||||
add SC, 1, SC
|
add SC, 1, SC
|
||||||
|
|
||||||
! We get here if the divisor overflowed while shifting.
|
! We get here if the divisor overflowed while shifting.
|
||||||
@ -155,14 +147,14 @@ ifelse(OP, `div',
|
|||||||
sll T, TOPBITS, T ! high order bit
|
sll T, TOPBITS, T ! high order bit
|
||||||
srl V, 1, V ! rest of V
|
srl V, 1, V ! rest of V
|
||||||
add V, T, V
|
add V, T, V
|
||||||
b Ldo_single_div
|
b LOC(do_single_div)
|
||||||
sub SC, 1, SC
|
sub SC, 1, SC
|
||||||
|
|
||||||
Lnot_too_big:
|
LOC(not_too_big):
|
||||||
3: cmp V, R
|
3: cmp V, R
|
||||||
blu 2b
|
blu 2b
|
||||||
nop
|
nop
|
||||||
be Ldo_single_div
|
be LOC(do_single_div)
|
||||||
nop
|
nop
|
||||||
/* NB: these are commented out in the V8-Sparc manual as well */
|
/* NB: these are commented out in the V8-Sparc manual as well */
|
||||||
/* (I do not understand this) */
|
/* (I do not understand this) */
|
||||||
@ -177,15 +169,15 @@ ifelse(OP, `div',
|
|||||||
! order bit set in the first step, just falling into the regular
|
! order bit set in the first step, just falling into the regular
|
||||||
! division loop will mess up the first time around.
|
! division loop will mess up the first time around.
|
||||||
! So we unroll slightly...
|
! So we unroll slightly...
|
||||||
Ldo_single_div:
|
LOC(do_single_div):
|
||||||
subcc SC, 1, SC
|
subcc SC, 1, SC
|
||||||
bl Lend_regular_divide
|
bl LOC(end_regular_divide)
|
||||||
nop
|
nop
|
||||||
sub R, V, R
|
sub R, V, R
|
||||||
mov 1, Q
|
mov 1, Q
|
||||||
b Lend_single_divloop
|
b LOC(end_single_divloop)
|
||||||
nop
|
nop
|
||||||
Lsingle_divloop:
|
LOC(single_divloop):
|
||||||
sll Q, 1, Q
|
sll Q, 1, Q
|
||||||
bl 1f
|
bl 1f
|
||||||
srl V, 1, V
|
srl V, 1, V
|
||||||
@ -197,37 +189,37 @@ ifelse(OP, `div',
|
|||||||
add R, V, R
|
add R, V, R
|
||||||
sub Q, 1, Q
|
sub Q, 1, Q
|
||||||
2:
|
2:
|
||||||
Lend_single_divloop:
|
LOC(end_single_divloop):
|
||||||
subcc SC, 1, SC
|
subcc SC, 1, SC
|
||||||
bge Lsingle_divloop
|
bge LOC(single_divloop)
|
||||||
tst R
|
tst R
|
||||||
b,a Lend_regular_divide
|
b,a LOC(end_regular_divide)
|
||||||
|
|
||||||
Lnot_really_big:
|
LOC(not_really_big):
|
||||||
1:
|
1:
|
||||||
sll V, N, V
|
sll V, N, V
|
||||||
cmp V, R
|
cmp V, R
|
||||||
bleu 1b
|
bleu 1b
|
||||||
addcc ITER, 1, ITER
|
addcc ITER, 1, ITER
|
||||||
be Lgot_result
|
be LOC(got_result)
|
||||||
sub ITER, 1, ITER
|
sub ITER, 1, ITER
|
||||||
|
|
||||||
tst R ! set up for initial iteration
|
tst R ! set up for initial iteration
|
||||||
Ldivloop:
|
LOC(divloop):
|
||||||
sll Q, N, Q
|
sll Q, N, Q
|
||||||
DEVELOP_QUOTIENT_BITS(1, 0)
|
DEVELOP_QUOTIENT_BITS(1, 0)
|
||||||
Lend_regular_divide:
|
LOC(end_regular_divide):
|
||||||
subcc ITER, 1, ITER
|
subcc ITER, 1, ITER
|
||||||
bge Ldivloop
|
bge LOC(divloop)
|
||||||
tst R
|
tst R
|
||||||
bl,a Lgot_result
|
bl,a LOC(got_result)
|
||||||
! non-restoring fixup here (one instruction only!)
|
! non-restoring fixup here (one instruction only!)
|
||||||
ifelse(OP, `div',
|
ifelse(OP, `div',
|
||||||
` sub Q, 1, Q
|
` sub Q, 1, Q
|
||||||
', ` add R, divisor, R
|
', ` add R, divisor, R
|
||||||
')
|
')
|
||||||
|
|
||||||
Lgot_result:
|
LOC(got_result):
|
||||||
ifelse(S, `true',
|
ifelse(S, `true',
|
||||||
` ! check to see if answer should be < 0
|
` ! check to see if answer should be < 0
|
||||||
tst SIGN
|
tst SIGN
|
||||||
@ -236,3 +228,5 @@ ifelse(S, `true',
|
|||||||
1:')
|
1:')
|
||||||
retl
|
retl
|
||||||
ifelse(OP, `div', `mov Q, %o0', `mov R, %o0')
|
ifelse(OP, `div', `mov Q, %o0', `mov R, %o0')
|
||||||
|
|
||||||
|
END(NAME)
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#define OPCODE_CALL 0x40000000 /* call ?; add PC-rel word address */
|
#define OPCODE_CALL 0x40000000 /* call ?; add PC-rel word address */
|
||||||
#define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */
|
#define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */
|
||||||
#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
|
#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
|
||||||
#define OPCODE_SAVE_SP64 0x9de3bfc0 /* save %sp, -64, %sp */
|
#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
|
||||||
|
|
||||||
|
|
||||||
/* Return nonzero iff E_MACHINE is compatible with the running host. */
|
/* Return nonzero iff E_MACHINE is compatible with the running host. */
|
||||||
@ -55,7 +55,7 @@ elf_machine_dynamic (void)
|
|||||||
static inline Elf32_Addr
|
static inline Elf32_Addr
|
||||||
elf_machine_load_address (void)
|
elf_machine_load_address (void)
|
||||||
{
|
{
|
||||||
register Elf32_Addr pc __asm("%o7"), got;
|
register Elf32_Addr pc __asm("%o7"), pic __asm("%l7"), got;
|
||||||
|
|
||||||
/* Utilize the fact that a local .got entry will be partially
|
/* Utilize the fact that a local .got entry will be partially
|
||||||
initialized at startup awaiting its RELATIVE fixup. */
|
initialized at startup awaiting its RELATIVE fixup. */
|
||||||
@ -64,50 +64,187 @@ elf_machine_load_address (void)
|
|||||||
".Load_address:\n\t"
|
".Load_address:\n\t"
|
||||||
"call 1f\n\t"
|
"call 1f\n\t"
|
||||||
"or %1,%%lo(.Load_address),%1\n"
|
"or %1,%%lo(.Load_address),%1\n"
|
||||||
"1:\tld [%%l7+%1],%1"
|
"1:\tld [%2+%1],%1"
|
||||||
: "=r"(pc), "=r"(got));
|
: "=r"(pc), "=r"(got) : "r"(pic));
|
||||||
|
|
||||||
return pc - got;
|
return pc - got;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf32_Addr addr;
|
/* Set up the loaded object described by L so its unrelocated PLT
|
||||||
|
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||||
|
|
||||||
asm (
|
static inline int
|
||||||
"add %%fp,0x44,%%o2\n\t" /* o2 = point to argc */
|
elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||||
"ld [%%o2 - 4],%%o0\n\t" /* o0 = load argc */
|
{
|
||||||
"sll %%o0, 2, %%o0\n\t" /* o0 = argc * sizeof (int) */
|
Elf32_Addr *plt;
|
||||||
"add %%o2,%%o0,%%o2\n\t" /* o2 = skip over argv */
|
extern void _dl_runtime_resolve (Elf32_Word);
|
||||||
"add %%o2,4,%%o2\n\t" /* skip over null after argv */
|
|
||||||
|
|
||||||
/* Now %o2 is pointing to env, skip over that as well. */
|
if (l->l_info[DT_JMPREL] && lazy)
|
||||||
"1:\n\t"
|
{
|
||||||
"ld [%%o2],%%o0\n\t"
|
/* The entries for functions in the PLT have not yet been filled in.
|
||||||
"cmp %%o0,0\n\t"
|
Their initial contents will arrange when called to set the high 22
|
||||||
"bnz 1b\n\t"
|
bits of %g1 with an offset into the .rela.plt section and jump to
|
||||||
"add %%o2,4,%%o2\n\t"
|
the beginning of the PLT. */
|
||||||
|
plt = (Elf32_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
|
||||||
|
|
||||||
/* Note that above, we want to advance the NULL after envp so
|
/* The beginning of the PLT does:
|
||||||
we always add 4. */
|
|
||||||
|
|
||||||
/* Now, search for the AT_BASE property. */
|
save %sp, -64, %sp
|
||||||
"2:\n\t"
|
pltpc: call _dl_runtime_resolve
|
||||||
"ld [%%o2],%%o0\n\t"
|
nop
|
||||||
"cmp %%o0,0\n\t"
|
.word MAP
|
||||||
"be,a 3f\n\t"
|
|
||||||
"or %%g0,%%g0,%0\n\t"
|
This saves the register window containing the arguments, and the
|
||||||
"cmp %%o0,7\n\t" /* AT_BASE = 7 */
|
PC value (pltpc) implicitly saved in %o7 by the call points near the
|
||||||
"be,a 3f\n\t"
|
location where we store the link_map pointer for this object. */
|
||||||
"ld [%%o2+4],%0\n\t"
|
|
||||||
"b 2b\n\t"
|
plt[0] = OPCODE_SAVE_SP;
|
||||||
"add %%o2,8,%%o2\n\t"
|
/* Construct PC-relative word address. */
|
||||||
/* At this point %0 has the load address for the interpreter */
|
plt[1] = OPCODE_CALL | (((Elf32_Addr) &_dl_runtime_resolve -
|
||||||
"3:\n\t"
|
(Elf32_Addr) &plt[1]) >> 2);
|
||||||
: "=r" (addr)
|
plt[2] = OPCODE_NOP; /* Fill call delay slot. */
|
||||||
: /* no inputs */
|
plt[3] = (Elf32_Addr) l;
|
||||||
: "o0", "o2");
|
}
|
||||||
return addr;
|
|
||||||
|
return lazy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This code is used in dl-runtime.c to call the `fixup' function
|
||||||
|
and then redirect to the address it returns. */
|
||||||
|
#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
|
||||||
|
.globl _dl_runtime_resolve
|
||||||
|
.type _dl_runtime_resolve, @function
|
||||||
|
_dl_runtime_resolve:
|
||||||
|
/* Set up the arguments to fixup --
|
||||||
|
%o0 = link_map out of plt0
|
||||||
|
%o1 = offset of reloc entry */
|
||||||
|
ld [%o7 + 8], %o0
|
||||||
|
srl %g1, 10, %o1
|
||||||
|
call fixup
|
||||||
|
sub %o1, 4*12, %o1
|
||||||
|
jmp %o0
|
||||||
|
restore
|
||||||
|
.size _dl_runtime_resolve, . - _dl_runtime_resolve");
|
||||||
|
|
||||||
|
/* The address of the JMP_SLOT reloc is the .plt entry, thus we don't
|
||||||
|
dereference the reloc's addr to get the final destination. Ideally
|
||||||
|
there would be a generic way to return the value of the symbol from
|
||||||
|
elf_machine_relplt, but as it is, the address of the .plt entry is
|
||||||
|
good enough. */
|
||||||
|
#define ELF_FIXUP_RETURN_VALUE(map, result) ((Elf32_Addr) &(result))
|
||||||
|
|
||||||
|
/* Nonzero iff TYPE should not be allowed to resolve to one of
|
||||||
|
the main executable's symbols, as for a COPY reloc. */
|
||||||
|
#define elf_machine_lookup_noexec_p(type) ((type) == R_SPARC_COPY)
|
||||||
|
|
||||||
|
/* Nonzero iff TYPE describes relocation of a PLT entry, so
|
||||||
|
PLT entries should not be allowed to define the value. */
|
||||||
|
#define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
|
||||||
|
|
||||||
|
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
|
||||||
|
#define ELF_MACHINE_RELOC_NOPLT R_SPARC_JMP_SLOT
|
||||||
|
|
||||||
|
/* The SPARC never uses Elf32_Rel relocations. */
|
||||||
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
|
||||||
|
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
|
||||||
|
#define ELF_MACHINE_PLTREL_OVERLAP 1
|
||||||
|
|
||||||
|
/* The PLT uses Elf32_Rela relocs. */
|
||||||
|
#define elf_machine_relplt elf_machine_rela
|
||||||
|
|
||||||
|
/* Initial entry point code for the dynamic linker.
|
||||||
|
The C function `_dl_start' is the real entry point;
|
||||||
|
its return value is the user program's entry point. */
|
||||||
|
|
||||||
|
#define RTLD_START __asm__ ("\
|
||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start,@function
|
||||||
|
_start:
|
||||||
|
/* Allocate space for functions to drop their arguments. */
|
||||||
|
sub %sp, 6*4, %sp
|
||||||
|
/* Pass pointer to argument block to _dl_start. */
|
||||||
|
call _dl_start
|
||||||
|
add %sp, 22*4, %o0
|
||||||
|
/* FALTHRU */
|
||||||
|
.globl _dl_start_user
|
||||||
|
.type _dl_start_user,@function
|
||||||
|
_dl_start_user:
|
||||||
|
/* Load the PIC register. */
|
||||||
|
1: call 2f
|
||||||
|
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
|
||||||
|
2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
|
||||||
|
add %l7, %o7, %l7
|
||||||
|
/* Save the user entry point address in %l0 */
|
||||||
|
mov %o0, %l0
|
||||||
|
/* See if we were run as a command with the executable file name as an
|
||||||
|
extra leading argument. If so, adjust the contents of the stack. */
|
||||||
|
sethi %hi(_dl_skip_args), %g2
|
||||||
|
or %g2, %lo(_dl_skip_args), %g2
|
||||||
|
ld [%l7+%g2], %i0
|
||||||
|
ld [%i0], %i0
|
||||||
|
tst %i0
|
||||||
|
beq 3f
|
||||||
|
nop
|
||||||
|
/* Find out how far to shift. */
|
||||||
|
ld [%sp+22*4], %i1 /* load argc */
|
||||||
|
sub %i1, %i0, %i1
|
||||||
|
sll %i0, 2, %i2
|
||||||
|
st %i1, [%sp+22*4]
|
||||||
|
add %sp, 23*4, %i1
|
||||||
|
add %i1, %i2, %i2
|
||||||
|
/* Copy down argv */
|
||||||
|
21: ld [%i2], %i3
|
||||||
|
add %i2, 4, %i2
|
||||||
|
tst %i3
|
||||||
|
st %i3, [%i1]
|
||||||
|
bne 21b
|
||||||
|
add %i1, 4, %i1
|
||||||
|
/* Copy down env */
|
||||||
|
22: ld [%i2], %i3
|
||||||
|
add %i2, 4, %i2
|
||||||
|
tst %i3
|
||||||
|
st %i3, [%i1]
|
||||||
|
bne 22b
|
||||||
|
add %i1, 4, %i1
|
||||||
|
/* Copy down auxiliary table. */
|
||||||
|
23: ld [%i2], %i3
|
||||||
|
ld [%i2+4], %i4
|
||||||
|
add %i2, 8, %i2
|
||||||
|
tst %i3
|
||||||
|
st %i3, [%i1]
|
||||||
|
st %i4, [%i1+4]
|
||||||
|
bne 23b
|
||||||
|
add %i1, 8, %i1
|
||||||
|
/* Load _dl_default_scope[2] to pass to _dl_init_next. */
|
||||||
|
3: sethi %hi(_dl_default_scope), %g1
|
||||||
|
or %g1, %lo(_dl_default_scope), %g1
|
||||||
|
ld [%l7+%g1], %l1
|
||||||
|
ld [%l1+2*4], %l1
|
||||||
|
/* Call _dl_init_next to return the address of an initializer to run. */
|
||||||
|
4: call _dl_init_next
|
||||||
|
mov %l1, %o0
|
||||||
|
tst %o0
|
||||||
|
beq 5f
|
||||||
|
nop
|
||||||
|
jmpl %o0, %o7
|
||||||
|
nop
|
||||||
|
ba,a 4b
|
||||||
|
/* Clear the startup flag. */
|
||||||
|
5: sethi %hi(_dl_starting_up), %g1
|
||||||
|
or %g1, %lo(_dl_starting_up), %g1
|
||||||
|
ld [%l7+%g1], %g1
|
||||||
|
st %g0, [%g1]
|
||||||
|
/* Pass our finalizer function to the user in %g1. */
|
||||||
|
sethi %hi(_dl_fini), %g1
|
||||||
|
or %g1, %lo(_dl_fini), %g1
|
||||||
|
ld [%l7+%g1], %g1
|
||||||
|
/* Jump to the user's entry point and deallocate the extra stack we got. */
|
||||||
|
jmp %l0
|
||||||
|
add %sp, 6*4, %sp
|
||||||
|
.size _dl_start_user,.-_dl_start_user");
|
||||||
|
|
||||||
#ifdef RESOLVE
|
#ifdef RESOLVE
|
||||||
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
|
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
|
||||||
MAP is the object containing the reloc. */
|
MAP is the object containing the reloc. */
|
||||||
@ -117,7 +254,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
|||||||
const Elf32_Sym *sym, const struct r_found_version *version,
|
const Elf32_Sym *sym, const struct r_found_version *version,
|
||||||
Elf32_Addr *const reloc_addr)
|
Elf32_Addr *const reloc_addr)
|
||||||
{
|
{
|
||||||
Elf32_Addr loadbase;
|
extern unsigned long _dl_hwcap;
|
||||||
|
|
||||||
if (ELF32_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE)
|
if (ELF32_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE)
|
||||||
{
|
{
|
||||||
@ -144,6 +281,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
|||||||
switch (ELF32_R_TYPE (reloc->r_info))
|
switch (ELF32_R_TYPE (reloc->r_info))
|
||||||
{
|
{
|
||||||
case R_SPARC_COPY:
|
case R_SPARC_COPY:
|
||||||
|
#ifndef RTLD_BOOTSTRAP
|
||||||
if (sym->st_size > refsym->st_size
|
if (sym->st_size > refsym->st_size
|
||||||
|| (_dl_verbose && sym->st_size < refsym->st_size))
|
|| (_dl_verbose && sym->st_size < refsym->st_size))
|
||||||
{
|
{
|
||||||
@ -159,14 +297,21 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
|||||||
}
|
}
|
||||||
memcpy (reloc_addr, (void *) value, MIN (sym->st_size,
|
memcpy (reloc_addr, (void *) value, MIN (sym->st_size,
|
||||||
refsym->st_size));
|
refsym->st_size));
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case R_SPARC_GLOB_DAT:
|
case R_SPARC_GLOB_DAT:
|
||||||
case R_SPARC_32:
|
case R_SPARC_32:
|
||||||
*reloc_addr = value;
|
*reloc_addr = value;
|
||||||
break;
|
break;
|
||||||
case R_SPARC_JMP_SLOT:
|
case R_SPARC_JMP_SLOT:
|
||||||
reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
|
/* For thread safety, write the instructions from the bottom and
|
||||||
|
flush before we overwrite the critical "b,a". */
|
||||||
reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
|
reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
|
||||||
|
if (1 || (_dl_hwcap & 1)) /* HWCAP_SPARC_FLUSH */
|
||||||
|
__asm __volatile ("flush %0+8" : : "r"(reloc_addr));
|
||||||
|
reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
|
||||||
|
if (1 || (_dl_hwcap & 1)) /* HWCAP_SPARC_FLUSH */
|
||||||
|
__asm __volatile ("flush %0+4" : : "r"(reloc_addr));
|
||||||
break;
|
break;
|
||||||
case R_SPARC_8:
|
case R_SPARC_8:
|
||||||
*(char *) reloc_addr = value;
|
*(char *) reloc_addr = value;
|
||||||
@ -218,146 +363,3 @@ elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* RESOLVE */
|
#endif /* RESOLVE */
|
||||||
|
|
||||||
/* Nonzero iff TYPE should not be allowed to resolve to one of
|
|
||||||
the main executable's symbols, as for a COPY reloc. */
|
|
||||||
#define elf_machine_lookup_noexec_p(type) ((type) == R_SPARC_COPY)
|
|
||||||
|
|
||||||
/* Nonzero iff TYPE describes relocation of a PLT entry, so
|
|
||||||
PLT entries should not be allowed to define the value. */
|
|
||||||
#define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
|
|
||||||
|
|
||||||
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
|
|
||||||
#define ELF_MACHINE_RELOC_NOPLT R_SPARC_JMP_SLOT
|
|
||||||
|
|
||||||
/* The SPARC never uses Elf32_Rel relocations. */
|
|
||||||
#define ELF_MACHINE_NO_REL 1
|
|
||||||
|
|
||||||
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
|
|
||||||
#define ELF_MACHINE_PLTREL_OVERLAP 1
|
|
||||||
|
|
||||||
/* Set up the loaded object described by L so its unrelocated PLT
|
|
||||||
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
|
||||||
{
|
|
||||||
Elf32_Addr *plt;
|
|
||||||
extern void _dl_runtime_resolve (Elf32_Word);
|
|
||||||
|
|
||||||
if (l->l_info[DT_JMPREL] && lazy)
|
|
||||||
{
|
|
||||||
/* The entries for functions in the PLT have not yet been filled in.
|
|
||||||
Their initial contents will arrange when called to set the high 22
|
|
||||||
bits of %g1 with an offset into the .rela.plt section and jump to
|
|
||||||
the beginning of the PLT. */
|
|
||||||
plt = (Elf32_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
|
|
||||||
|
|
||||||
/* The beginning of the PLT does:
|
|
||||||
|
|
||||||
save %sp, -64, %sp
|
|
||||||
pltpc: call _dl_runtime_resolve
|
|
||||||
nop
|
|
||||||
.word MAP
|
|
||||||
|
|
||||||
This saves the register window containing the arguments, and the
|
|
||||||
PC value (pltpc) implicitly saved in %o7 by the call points near the
|
|
||||||
location where we store the link_map pointer for this object. */
|
|
||||||
|
|
||||||
plt[0] = OPCODE_SAVE_SP64; /* save %sp, -64, %sp */
|
|
||||||
/* Construct PC-relative word address. */
|
|
||||||
plt[1] = OPCODE_CALL | (((Elf32_Addr) &_dl_runtime_resolve -
|
|
||||||
(Elf32_Addr) &plt[1]) >> 2);
|
|
||||||
plt[2] = OPCODE_NOP; /* Fill call delay slot. */
|
|
||||||
plt[3] = (Elf32_Addr *) l;
|
|
||||||
}
|
|
||||||
|
|
||||||
return lazy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This code is used in dl-runtime.c to call the `fixup' function
|
|
||||||
and then redirect to the address it returns. */
|
|
||||||
#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
|
|
||||||
# Trampoline for _dl_runtime_resolver
|
|
||||||
.globl _dl_runtime_resolve
|
|
||||||
.type _dl_runtime_resolve, @function
|
|
||||||
_dl_runtime_resolve:
|
|
||||||
t 1
|
|
||||||
#call %g0
|
|
||||||
# Pass two args to fixup: the PLT address computed from the PC saved
|
|
||||||
# in the PLT's call insn, and the reloc offset passed in %g1.
|
|
||||||
#ld [%o7 + 8], %o1 | Second arg, loaded from PLTPC[2].
|
|
||||||
#call fixup
|
|
||||||
#shrl %g1, 22, %o0 | First arg, set in delay slot of call.
|
|
||||||
# Jump to the real function.
|
|
||||||
#jmpl %o0, %g0
|
|
||||||
# In the delay slot of that jump, restore the register window
|
|
||||||
# saved by the first insn of the PLT.
|
|
||||||
#restore
|
|
||||||
.size _dl_runtime_resolve, . - _dl_runtime_resolve
|
|
||||||
");
|
|
||||||
|
|
||||||
/* The PLT uses Elf32_Rela relocs. */
|
|
||||||
#define elf_machine_relplt elf_machine_rela
|
|
||||||
|
|
||||||
|
|
||||||
/* Mask identifying addresses reserved for the user program,
|
|
||||||
where the dynamic linker should not map anything. */
|
|
||||||
#define ELF_MACHINE_USER_ADDRESS_MASK ???
|
|
||||||
|
|
||||||
/* Initial entry point code for the dynamic linker.
|
|
||||||
The C function `_dl_start' is the real entry point;
|
|
||||||
its return value is the user program's entry point. */
|
|
||||||
|
|
||||||
#define RTLD_START __asm__ ( \
|
|
||||||
".text\n\
|
|
||||||
.globl _start\n\
|
|
||||||
.type _start,@function\n\
|
|
||||||
_start:\n\
|
|
||||||
/* Pass pointer to argument block to _dl_start. */\n\
|
|
||||||
add %sp,64,%o0\n\
|
|
||||||
call _dl_start\n\
|
|
||||||
nop\n\
|
|
||||||
\n\
|
|
||||||
mov %o0,%l0\n\
|
|
||||||
\n\
|
|
||||||
2:\n\
|
|
||||||
call 1f\n\
|
|
||||||
nop\n\
|
|
||||||
1:\n\
|
|
||||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-(2b-.)),%l2\n\
|
|
||||||
sethi %hi(_dl_default_scope),%l3\n\
|
|
||||||
or %l2,%lo(_GLOBAL_OFFSET_TABLE_-(2b-.)),%l2\n\
|
|
||||||
or %l3,%lo(_dl_default_scope),%l3\n\
|
|
||||||
add %o7,%l2,%l1\n\
|
|
||||||
# %l1 has the GOT. %l3 has _dl_default_scope GOT offset\n\
|
|
||||||
ld [%l1+%l3],%l4\n\
|
|
||||||
# %l4 has pointer to _dl_default_scope. Now, load _dl_default_scope [2]\n\
|
|
||||||
ld [%l4+8],%l4\n\
|
|
||||||
# %l4 has _dl_default_scope [2]\n\
|
|
||||||
# call _dl_init_next until it returns 0, pass _dl_default_scope [2]\n\
|
|
||||||
3:\n\
|
|
||||||
call _dl_init_next\n\
|
|
||||||
mov %l4,%o0\n\
|
|
||||||
cmp %o0,%g0\n\
|
|
||||||
bz,a 4f\n\
|
|
||||||
nop\n\
|
|
||||||
call %o0\n\
|
|
||||||
/* Pass pointer to argument block to this init function */\n\
|
|
||||||
add %sp,64,%o0\n\
|
|
||||||
b,a 3b\n\
|
|
||||||
4:\n\
|
|
||||||
# Clear the _dl_starting_up variable and pass _dl_fini in %g1 as per ELF ABI.\n\
|
|
||||||
sethi %hi(_dl_starting_up),%l4\n\
|
|
||||||
sethi %hi(_dl_fini),%l3\n\
|
|
||||||
or %l4,%lo(_dl_starting_up),%l4\n\
|
|
||||||
or %l3,%lo(_dl_fini),%l3\n\
|
|
||||||
# clear _dl_starting_up\n\
|
|
||||||
ld [%l1+%l4],%l5\n\
|
|
||||||
st %g0,[%l5]\n\
|
|
||||||
# load out fini function for atexit in %g1\n\
|
|
||||||
ld [%l3+%l1],%g1\n\
|
|
||||||
# jump to the user program entry point.\n\
|
|
||||||
jmpl %l0,%g0\n\
|
|
||||||
nop\n\
|
|
||||||
");
|
|
||||||
|
@ -10,11 +10,13 @@
|
|||||||
* This code optimizes short (less than 13-bit) multiplies.
|
* This code optimizes short (less than 13-bit) multiplies.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
|
||||||
ENTRY(.mul)
|
ENTRY(.mul)
|
||||||
mov %o0, %y ! multiplier -> Y
|
mov %o0, %y ! multiplier -> Y
|
||||||
andncc %o0, 0xfff, %g0 ! test bits 12..31
|
andncc %o0, 0xfff, %g0 ! test bits 12..31
|
||||||
be Lmul_shortway ! if zero, can do it the short way
|
be LOC(mul_shortway) ! if zero, can do it the short way
|
||||||
andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
|
andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -81,7 +83,7 @@ ENTRY(.mul)
|
|||||||
! and put upper half in place
|
! and put upper half in place
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Lmul_shortway:
|
LOC(mul_shortway):
|
||||||
/*
|
/*
|
||||||
* Short multiply. 12 steps, followed by a final shift step.
|
* Short multiply. 12 steps, followed by a final shift step.
|
||||||
* The resulting bits are off by 12 and (32-12) = 20 bit positions,
|
* The resulting bits are off by 12 and (32-12) = 20 bit positions,
|
||||||
@ -121,3 +123,5 @@ Lmul_shortway:
|
|||||||
or %o5, %o0, %o0 ! construct low part of result
|
or %o5, %o0, %o0 ! construct low part of result
|
||||||
retl
|
retl
|
||||||
sra %o4, 20, %o1 ! ... and extract high part of result
|
sra %o4, 20, %o1 ! ... and extract high part of result
|
||||||
|
|
||||||
|
END(.mul)
|
||||||
|
86
sysdeps/sparc/sparc32/elf/start.S
Normal file
86
sysdeps/sparc/sparc32/elf/start.S
Normal 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
|
@ -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));
|
|
||||||
}
|
|
@ -72,5 +72,5 @@ typedef unsigned int fenv_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For internal use only: access the fp state register. */
|
/* For internal use only: access the fp state register. */
|
||||||
#define __fenv_stfsr(X) __asm__("stfsr %0" : "=m"(X))
|
#define __fenv_stfsr(X) __asm__("st %%fsr,%0" : "=m"(X))
|
||||||
#define __fenv_ldfsr(X) __asm__ __volatile__("ldfsr %0" : : "m"(X))
|
#define __fenv_ldfsr(X) __asm__ __volatile__("ld %0,%%fsr" : : "m"(X))
|
||||||
|
@ -41,13 +41,11 @@
|
|||||||
|
|
||||||
/* Now two recommended cw */
|
/* Now two recommended cw */
|
||||||
|
|
||||||
/* Linux default:
|
/* Linux and IEEE default:
|
||||||
- extended precision
|
- extended precision
|
||||||
- rounding to nearest
|
- rounding to nearest
|
||||||
- exceptions on overflow, zero divide and NaN */
|
- no exceptions. */
|
||||||
#define _FPU_DEFAULT 0x1e
|
#define _FPU_DEFAULT 0x0
|
||||||
|
|
||||||
/* IEEE: same as above, but exceptions */
|
|
||||||
#define _FPU_IEEE 0x0
|
#define _FPU_IEEE 0x0
|
||||||
|
|
||||||
/* Type of the control word. */
|
/* Type of the control word. */
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
! sparc __mpn_lshift --
|
! Sparc __mpn_lshift --
|
||||||
|
!
|
||||||
! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
!
|
||||||
! This file is part of the GNU MP Library.
|
! This file is part of the GNU MP Library.
|
||||||
|
!
|
||||||
! The GNU MP Library is free software; you can redistribute it and/or modify
|
! The GNU MP Library is free software; you can redistribute it and/or modify
|
||||||
! it under the terms of the GNU Library General Public License as published by
|
! it under the terms of the GNU Library General Public License as published by
|
||||||
! the Free Software Foundation; either version 2 of the License, or (at your
|
! the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
! option) any later version.
|
! option) any later version.
|
||||||
|
!
|
||||||
! The GNU MP Library is distributed in the hope that it will be useful, but
|
! The GNU MP Library is distributed in the hope that it will be useful, but
|
||||||
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
! License for more details.
|
! License for more details.
|
||||||
|
!
|
||||||
! You should have received a copy of the GNU Library General Public License
|
! You should have received a copy of the GNU Library General Public License
|
||||||
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||||
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
@ -21,17 +21,14 @@
|
|||||||
|
|
||||||
|
|
||||||
! INPUT PARAMETERS
|
! INPUT PARAMETERS
|
||||||
! res_ptr %o0
|
! RES_PTR %o0
|
||||||
! src_ptr %o1
|
! SRC_PTR %o1
|
||||||
! size %o2
|
! SIZE %o2
|
||||||
! cnt %o3
|
! CNT %o3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_lshift)
|
||||||
.align 4
|
|
||||||
.global C_SYMBOL_NAME(__mpn_lshift)
|
|
||||||
C_SYMBOL_NAME(__mpn_lshift):
|
|
||||||
sll %o2,2,%g1
|
sll %o2,2,%g1
|
||||||
add %o1,%g1,%o1 ! make %o1 point at end of src
|
add %o1,%g1,%o1 ! make %o1 point at end of src
|
||||||
ld [%o1-4],%g2 ! load first limb
|
ld [%o1-4],%g2 ! load first limb
|
||||||
@ -40,12 +37,13 @@ C_SYMBOL_NAME(__mpn_lshift):
|
|||||||
add %o2,-1,%o2
|
add %o2,-1,%o2
|
||||||
andcc %o2,4-1,%g4 ! number of limbs in first loop
|
andcc %o2,4-1,%g4 ! number of limbs in first loop
|
||||||
srl %g2,%o5,%g1 ! compute function result
|
srl %g2,%o5,%g1 ! compute function result
|
||||||
be L0 ! if multiple of 4 limbs, skip first loop
|
be LOC(0) ! if multiple of 4 limbs, skip first loop
|
||||||
st %g1,[%sp+80]
|
st %g1,[%sp+80]
|
||||||
|
|
||||||
sub %o2,%g4,%o2 ! adjust count for main loop
|
sub %o2,%g4,%o2 ! adjust count for main loop
|
||||||
|
|
||||||
Loop0: ld [%o1-8],%g3
|
LOC(loop0):
|
||||||
|
ld [%o1-8],%g3
|
||||||
add %o0,-4,%o0
|
add %o0,-4,%o0
|
||||||
add %o1,-4,%o1
|
add %o1,-4,%o1
|
||||||
addcc %g4,-1,%g4
|
addcc %g4,-1,%g4
|
||||||
@ -53,14 +51,15 @@ Loop0: ld [%o1-8],%g3
|
|||||||
srl %g3,%o5,%g1
|
srl %g3,%o5,%g1
|
||||||
mov %g3,%g2
|
mov %g3,%g2
|
||||||
or %o4,%g1,%o4
|
or %o4,%g1,%o4
|
||||||
bne Loop0
|
bne LOC(loop0)
|
||||||
st %o4,[%o0+0]
|
st %o4,[%o0+0]
|
||||||
|
|
||||||
L0: tst %o2
|
LOC(0): tst %o2
|
||||||
be Lend
|
be LOC(end)
|
||||||
nop
|
nop
|
||||||
|
|
||||||
Loop: ld [%o1-8],%g3
|
LOC(loop):
|
||||||
|
ld [%o1-8],%g3
|
||||||
add %o0,-16,%o0
|
add %o0,-16,%o0
|
||||||
addcc %o2,-4,%o2
|
addcc %o2,-4,%o2
|
||||||
sll %g2,%o3,%o4
|
sll %g2,%o3,%o4
|
||||||
@ -86,10 +85,13 @@ Loop: ld [%o1-8],%g3
|
|||||||
|
|
||||||
add %o1,-16,%o1
|
add %o1,-16,%o1
|
||||||
or %g4,%g1,%g4
|
or %g4,%g1,%g4
|
||||||
bne Loop
|
bne LOC(loop)
|
||||||
st %g4,[%o0+0]
|
st %g4,[%o0+0]
|
||||||
|
|
||||||
Lend: sll %g2,%o3,%g2
|
LOC(end):
|
||||||
|
sll %g2,%o3,%g2
|
||||||
st %g2,[%o0-4]
|
st %g2,[%o0-4]
|
||||||
retl
|
retl
|
||||||
ld [%sp+80],%o0
|
ld [%sp+80],%o0
|
||||||
|
|
||||||
|
END(__mpn_lshift)
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
! SPARC __mpn_mul_1 -- Multiply a limb vector with a limb and store
|
! SPARC __mpn_mul_1 -- Multiply a limb vector with a limb and store
|
||||||
! the result in a second limb vector.
|
! the result in a second limb vector.
|
||||||
|
!
|
||||||
! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
|
! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
|
||||||
|
!
|
||||||
! This file is part of the GNU MP Library.
|
! This file is part of the GNU MP Library.
|
||||||
|
!
|
||||||
! The GNU MP Library is free software; you can redistribute it and/or modify
|
! The GNU MP Library is free software; you can redistribute it and/or modify
|
||||||
! it under the terms of the GNU Library General Public License as published by
|
! it under the terms of the GNU Library General Public License as published by
|
||||||
! the Free Software Foundation; either version 2 of the License, or (at your
|
! the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
! option) any later version.
|
! option) any later version.
|
||||||
|
!
|
||||||
! The GNU MP Library is distributed in the hope that it will be useful, but
|
! The GNU MP Library is distributed in the hope that it will be useful, but
|
||||||
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
! License for more details.
|
! License for more details.
|
||||||
|
!
|
||||||
! You should have received a copy of the GNU Library General Public License
|
! You should have received a copy of the GNU Library General Public License
|
||||||
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||||
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
@ -22,10 +22,10 @@
|
|||||||
|
|
||||||
|
|
||||||
! INPUT PARAMETERS
|
! INPUT PARAMETERS
|
||||||
! res_ptr o0
|
! RES_PTR o0
|
||||||
! s1_ptr o1
|
! S1_PTR o1
|
||||||
! size o2
|
! SIZE o2
|
||||||
! s2_limb o3
|
! S2_LIMB o3
|
||||||
|
|
||||||
! ADD CODE FOR SMALL MULTIPLIERS!
|
! ADD CODE FOR SMALL MULTIPLIERS!
|
||||||
!1: ld
|
!1: ld
|
||||||
@ -89,12 +89,9 @@
|
|||||||
! sll a,29,y2
|
! sll a,29,y2
|
||||||
! st x,
|
! st x,
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_mul_1)
|
||||||
.align 4
|
|
||||||
.global C_SYMBOL_NAME(__mpn_mul_1)
|
|
||||||
C_SYMBOL_NAME(__mpn_mul_1):
|
|
||||||
! Make S1_PTR and RES_PTR point at the end of their blocks
|
! Make S1_PTR and RES_PTR point at the end of their blocks
|
||||||
! and put (- 4 x SIZE) in index/loop counter.
|
! and put (- 4 x SIZE) in index/loop counter.
|
||||||
sll %o2,2,%o2
|
sll %o2,2,%o2
|
||||||
@ -103,16 +100,16 @@ C_SYMBOL_NAME(__mpn_mul_1):
|
|||||||
sub %g0,%o2,%o2
|
sub %g0,%o2,%o2
|
||||||
|
|
||||||
cmp %o3,0xfff
|
cmp %o3,0xfff
|
||||||
bgu Large
|
bgu LOC(large)
|
||||||
nop
|
nop
|
||||||
|
|
||||||
ld [%o1+%o2],%o5
|
ld [%o1+%o2],%o5
|
||||||
mov 0,%o0
|
mov 0,%o0
|
||||||
b L0
|
b LOC(0)
|
||||||
add %o4,-4,%o4
|
add %o4,-4,%o4
|
||||||
Loop0:
|
LOC(loop0):
|
||||||
st %g1,[%o4+%o2]
|
st %g1,[%o4+%o2]
|
||||||
L0: wr %g0,%o3,%y
|
LOC(0): wr %g0,%o3,%y
|
||||||
sra %o5,31,%g2
|
sra %o5,31,%g2
|
||||||
and %o3,%g2,%g2
|
and %o3,%g2,%g2
|
||||||
andcc %g1,0,%g1
|
andcc %g1,0,%g1
|
||||||
@ -138,21 +135,22 @@ L0: wr %g0,%o3,%y
|
|||||||
addcc %g1,%o0,%g1
|
addcc %g1,%o0,%g1
|
||||||
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
|
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
|
||||||
addcc %o2,4,%o2 ! loop counter
|
addcc %o2,4,%o2 ! loop counter
|
||||||
bne,a Loop0
|
bne,a LOC(loop0)
|
||||||
ld [%o1+%o2],%o5
|
ld [%o1+%o2],%o5
|
||||||
|
|
||||||
retl
|
retl
|
||||||
st %g1,[%o4+%o2]
|
st %g1,[%o4+%o2]
|
||||||
|
|
||||||
|
|
||||||
Large: ld [%o1+%o2],%o5
|
LOC(large):
|
||||||
|
ld [%o1+%o2],%o5
|
||||||
mov 0,%o0
|
mov 0,%o0
|
||||||
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
|
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
|
||||||
b L1
|
b LOC(1)
|
||||||
add %o4,-4,%o4
|
add %o4,-4,%o4
|
||||||
Loop:
|
LOC(loop):
|
||||||
st %g3,[%o4+%o2]
|
st %g3,[%o4+%o2]
|
||||||
L1: wr %g0,%o5,%y
|
LOC(1): wr %g0,%o5,%y
|
||||||
and %o5,%g4,%g2 ! g2 = S1_LIMB iff S2_LIMB < 0, else 0
|
and %o5,%g4,%g2 ! g2 = S1_LIMB iff S2_LIMB < 0, else 0
|
||||||
andcc %g0,%g0,%g1
|
andcc %g0,%g0,%g1
|
||||||
mulscc %g1,%o3,%g1
|
mulscc %g1,%o3,%g1
|
||||||
@ -192,8 +190,10 @@ L1: wr %g0,%o5,%y
|
|||||||
addcc %g3,%o0,%g3
|
addcc %g3,%o0,%g3
|
||||||
addx %g2,%g1,%o0 ! add sign-compensation and cy to hi limb
|
addx %g2,%g1,%o0 ! add sign-compensation and cy to hi limb
|
||||||
addcc %o2,4,%o2 ! loop counter
|
addcc %o2,4,%o2 ! loop counter
|
||||||
bne,a Loop
|
bne,a LOC(loop)
|
||||||
ld [%o1+%o2],%o5
|
ld [%o1+%o2],%o5
|
||||||
|
|
||||||
retl
|
retl
|
||||||
st %g3,[%o4+%o2]
|
st %g3,[%o4+%o2]
|
||||||
|
|
||||||
|
END(__mpn_mul_1)
|
||||||
|
@ -37,22 +37,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
#ifdef __linux__
|
|
||||||
#include <asm/traps.h>
|
|
||||||
#else
|
|
||||||
#ifdef __svr4__
|
|
||||||
#include <sys/trap.h>
|
#include <sys/trap.h>
|
||||||
#else
|
|
||||||
#include <machine/trap.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ENTRY(.rem)
|
ENTRY(.rem)
|
||||||
! compute sign of result; if neither is negative, no problem
|
! compute sign of result; if neither is negative, no problem
|
||||||
orcc %o1, %o0, %g0 ! either negative?
|
orcc %o1, %o0, %g0 ! either negative?
|
||||||
bge 2f ! no, go do the divide
|
bge 2f ! no, go do the divide
|
||||||
mov %o0, %g6 ! sign of remainder matches %o0
|
mov %o0, %g3 ! sign of remainder matches %o0
|
||||||
tst %o1
|
tst %o1
|
||||||
bge 1f
|
bge 1f
|
||||||
tst %o0
|
tst %o0
|
||||||
@ -76,11 +68,11 @@ ENTRY(.rem)
|
|||||||
|
|
||||||
1:
|
1:
|
||||||
cmp %o3, %o5 ! if %o1 exceeds %o0, done
|
cmp %o3, %o5 ! if %o1 exceeds %o0, done
|
||||||
blu Lgot_result ! (and algorithm fails otherwise)
|
blu LOC(got_result) ! (and algorithm fails otherwise)
|
||||||
clr %o2
|
clr %o2
|
||||||
sethi %hi(1 << (32 - 4 - 1)), %g1
|
sethi %hi(1 << (32 - 4 - 1)), %g1
|
||||||
cmp %o3, %g1
|
cmp %o3, %g1
|
||||||
blu Lnot_really_big
|
blu LOC(not_really_big)
|
||||||
clr %o4
|
clr %o4
|
||||||
|
|
||||||
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
||||||
@ -91,15 +83,15 @@ ENTRY(.rem)
|
|||||||
1:
|
1:
|
||||||
cmp %o5, %g1
|
cmp %o5, %g1
|
||||||
bgeu 3f
|
bgeu 3f
|
||||||
mov 1, %g7
|
mov 1, %g2
|
||||||
sll %o5, 4, %o5
|
sll %o5, 4, %o5
|
||||||
b 1b
|
b 1b
|
||||||
add %o4, 1, %o4
|
add %o4, 1, %o4
|
||||||
|
|
||||||
! Now compute %g7.
|
! Now compute %g2.
|
||||||
2: addcc %o5, %o5, %o5
|
2: addcc %o5, %o5, %o5
|
||||||
bcc Lnot_too_big
|
bcc LOC(not_too_big)
|
||||||
add %g7, 1, %g7
|
add %g2, 1, %g2
|
||||||
|
|
||||||
! We get here if the %o1 overflowed while shifting.
|
! We get here if the %o1 overflowed while shifting.
|
||||||
! This means that %o3 has the high-order bit set.
|
! This means that %o3 has the high-order bit set.
|
||||||
@ -107,20 +99,20 @@ ENTRY(.rem)
|
|||||||
sll %g1, 4, %g1 ! high order bit
|
sll %g1, 4, %g1 ! high order bit
|
||||||
srl %o5, 1, %o5 ! rest of %o5
|
srl %o5, 1, %o5 ! rest of %o5
|
||||||
add %o5, %g1, %o5
|
add %o5, %g1, %o5
|
||||||
b Ldo_single_div
|
b LOC(do_single_div)
|
||||||
sub %g7, 1, %g7
|
sub %g2, 1, %g2
|
||||||
|
|
||||||
Lnot_too_big:
|
LOC(not_too_big):
|
||||||
3: cmp %o5, %o3
|
3: cmp %o5, %o3
|
||||||
blu 2b
|
blu 2b
|
||||||
nop
|
nop
|
||||||
be Ldo_single_div
|
be LOC(do_single_div)
|
||||||
nop
|
nop
|
||||||
/* NB: these are commented out in the V8-Sparc manual as well */
|
/* NB: these are commented out in the V8-Sparc manual as well */
|
||||||
/* (I do not understand this) */
|
/* (I do not understand this) */
|
||||||
! %o5 > %o3: went too far: back up 1 step
|
! %o5 > %o3: went too far: back up 1 step
|
||||||
! srl %o5, 1, %o5
|
! srl %o5, 1, %o5
|
||||||
! dec %g7
|
! dec %g2
|
||||||
! do single-bit divide steps
|
! do single-bit divide steps
|
||||||
!
|
!
|
||||||
! We have to be careful here. We know that %o3 >= %o5, so we can do the
|
! We have to be careful here. We know that %o3 >= %o5, so we can do the
|
||||||
@ -129,15 +121,15 @@ ENTRY(.rem)
|
|||||||
! order bit set in the first step, just falling into the regular
|
! order bit set in the first step, just falling into the regular
|
||||||
! division loop will mess up the first time around.
|
! division loop will mess up the first time around.
|
||||||
! So we unroll slightly...
|
! So we unroll slightly...
|
||||||
Ldo_single_div:
|
LOC(do_single_div):
|
||||||
subcc %g7, 1, %g7
|
subcc %g2, 1, %g2
|
||||||
bl Lend_regular_divide
|
bl LOC(end_regular_divide)
|
||||||
nop
|
nop
|
||||||
sub %o3, %o5, %o3
|
sub %o3, %o5, %o3
|
||||||
mov 1, %o2
|
mov 1, %o2
|
||||||
b Lend_single_divloop
|
b LOC(end_single_divloop)
|
||||||
nop
|
nop
|
||||||
Lsingle_divloop:
|
LOC(single_divloop):
|
||||||
sll %o2, 1, %o2
|
sll %o2, 1, %o2
|
||||||
bl 1f
|
bl 1f
|
||||||
srl %o5, 1, %o5
|
srl %o5, 1, %o5
|
||||||
@ -149,221 +141,223 @@ ENTRY(.rem)
|
|||||||
add %o3, %o5, %o3
|
add %o3, %o5, %o3
|
||||||
sub %o2, 1, %o2
|
sub %o2, 1, %o2
|
||||||
2:
|
2:
|
||||||
Lend_single_divloop:
|
LOC(end_single_divloop):
|
||||||
subcc %g7, 1, %g7
|
subcc %g2, 1, %g2
|
||||||
bge Lsingle_divloop
|
bge LOC(single_divloop)
|
||||||
tst %o3
|
tst %o3
|
||||||
b,a Lend_regular_divide
|
b,a LOC(end_regular_divide)
|
||||||
|
|
||||||
Lnot_really_big:
|
LOC(not_really_big):
|
||||||
1:
|
1:
|
||||||
sll %o5, 4, %o5
|
sll %o5, 4, %o5
|
||||||
cmp %o5, %o3
|
cmp %o5, %o3
|
||||||
bleu 1b
|
bleu 1b
|
||||||
addcc %o4, 1, %o4
|
addcc %o4, 1, %o4
|
||||||
be Lgot_result
|
be LOC(got_result)
|
||||||
sub %o4, 1, %o4
|
sub %o4, 1, %o4
|
||||||
|
|
||||||
tst %o3 ! set up for initial iteration
|
tst %o3 ! set up for initial iteration
|
||||||
Ldivloop:
|
LOC(divloop):
|
||||||
sll %o2, 4, %o2
|
sll %o2, 4, %o2
|
||||||
! depth 1, accumulated bits 0
|
! depth 1, accumulated bits 0
|
||||||
bl L.1.16
|
bl LOC(1.16)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 2, accumulated bits 1
|
! depth 2, accumulated bits 1
|
||||||
bl L.2.17
|
bl LOC(2.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits 3
|
! depth 3, accumulated bits 3
|
||||||
bl L.3.19
|
bl LOC(3.19)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 7
|
! depth 4, accumulated bits 7
|
||||||
bl L.4.23
|
bl LOC(4.23)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (7*2+1), %o2
|
add %o2, (7*2+1), %o2
|
||||||
|
|
||||||
L.4.23:
|
LOC(4.23):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (7*2-1), %o2
|
add %o2, (7*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.19:
|
LOC(3.19):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 5
|
! depth 4, accumulated bits 5
|
||||||
bl L.4.21
|
bl LOC(4.21)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (5*2+1), %o2
|
add %o2, (5*2+1), %o2
|
||||||
|
|
||||||
L.4.21:
|
LOC(4.21):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (5*2-1), %o2
|
add %o2, (5*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.2.17:
|
LOC(2.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits 1
|
! depth 3, accumulated bits 1
|
||||||
bl L.3.17
|
bl LOC(3.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 3
|
! depth 4, accumulated bits 3
|
||||||
bl L.4.19
|
bl LOC(4.19)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (3*2+1), %o2
|
add %o2, (3*2+1), %o2
|
||||||
|
|
||||||
L.4.19:
|
LOC(4.19):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (3*2-1), %o2
|
add %o2, (3*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.17:
|
LOC(3.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 1
|
! depth 4, accumulated bits 1
|
||||||
bl L.4.17
|
bl LOC(4.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (1*2+1), %o2
|
add %o2, (1*2+1), %o2
|
||||||
|
|
||||||
L.4.17:
|
LOC(4.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (1*2-1), %o2
|
add %o2, (1*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.1.16:
|
LOC(1.16):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 2, accumulated bits -1
|
! depth 2, accumulated bits -1
|
||||||
bl L.2.15
|
bl LOC(2.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits -1
|
! depth 3, accumulated bits -1
|
||||||
bl L.3.15
|
bl LOC(3.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -1
|
! depth 4, accumulated bits -1
|
||||||
bl L.4.15
|
bl LOC(4.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-1*2+1), %o2
|
add %o2, (-1*2+1), %o2
|
||||||
|
|
||||||
L.4.15:
|
LOC(4.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-1*2-1), %o2
|
add %o2, (-1*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.15:
|
LOC(3.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -3
|
! depth 4, accumulated bits -3
|
||||||
bl L.4.13
|
bl LOC(4.13)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-3*2+1), %o2
|
add %o2, (-3*2+1), %o2
|
||||||
|
|
||||||
L.4.13:
|
LOC(4.13):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-3*2-1), %o2
|
add %o2, (-3*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.2.15:
|
LOC(2.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits -3
|
! depth 3, accumulated bits -3
|
||||||
bl L.3.13
|
bl LOC(3.13)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -5
|
! depth 4, accumulated bits -5
|
||||||
bl L.4.11
|
bl LOC(4.11)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-5*2+1), %o2
|
add %o2, (-5*2+1), %o2
|
||||||
|
|
||||||
L.4.11:
|
LOC(4.11):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-5*2-1), %o2
|
add %o2, (-5*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.13:
|
LOC(3.13):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -7
|
! depth 4, accumulated bits -7
|
||||||
bl L.4.9
|
bl LOC(4.9)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-7*2+1), %o2
|
add %o2, (-7*2+1), %o2
|
||||||
|
|
||||||
L.4.9:
|
LOC(4.9):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-7*2-1), %o2
|
add %o2, (-7*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
9:
|
9:
|
||||||
Lend_regular_divide:
|
LOC(end_regular_divide):
|
||||||
subcc %o4, 1, %o4
|
subcc %o4, 1, %o4
|
||||||
bge Ldivloop
|
bge LOC(divloop)
|
||||||
tst %o3
|
tst %o3
|
||||||
bl,a Lgot_result
|
bl,a LOC(got_result)
|
||||||
! non-restoring fixup here (one instruction only!)
|
! non-restoring fixup here (one instruction only!)
|
||||||
add %o3, %o1, %o3
|
add %o3, %o1, %o3
|
||||||
|
|
||||||
|
|
||||||
Lgot_result:
|
LOC(got_result):
|
||||||
! check to see if answer should be < 0
|
! check to see if answer should be < 0
|
||||||
tst %g6
|
tst %g3
|
||||||
bl,a 1f
|
bl,a 1f
|
||||||
sub %g0, %o3, %o3
|
sub %g0, %o3, %o3
|
||||||
1:
|
1:
|
||||||
retl
|
retl
|
||||||
mov %o3, %o0
|
mov %o3, %o0
|
||||||
|
|
||||||
|
END(.rem)
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
! sparc __mpn_rshift --
|
! sparc __mpn_rshift --
|
||||||
|
!
|
||||||
! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
!
|
||||||
! This file is part of the GNU MP Library.
|
! This file is part of the GNU MP Library.
|
||||||
|
!
|
||||||
! The GNU MP Library is free software; you can redistribute it and/or modify
|
! The GNU MP Library is free software; you can redistribute it and/or modify
|
||||||
! it under the terms of the GNU Library General Public License as published by
|
! it under the terms of the GNU Library General Public License as published by
|
||||||
! the Free Software Foundation; either version 2 of the License, or (at your
|
! the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
! option) any later version.
|
! option) any later version.
|
||||||
|
!
|
||||||
! The GNU MP Library is distributed in the hope that it will be useful, but
|
! The GNU MP Library is distributed in the hope that it will be useful, but
|
||||||
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
! License for more details.
|
! License for more details.
|
||||||
|
!
|
||||||
! You should have received a copy of the GNU Library General Public License
|
! You should have received a copy of the GNU Library General Public License
|
||||||
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||||
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
@ -21,28 +21,26 @@
|
|||||||
|
|
||||||
|
|
||||||
! INPUT PARAMETERS
|
! INPUT PARAMETERS
|
||||||
! res_ptr %o0
|
! RES_PTR %o0
|
||||||
! src_ptr %o1
|
! SRC_PTR %o1
|
||||||
! size %o2
|
! SIZE %o2
|
||||||
! cnt %o3
|
! CNT %o3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_rshift)
|
||||||
.align 4
|
|
||||||
.global C_SYMBOL_NAME(__mpn_rshift)
|
|
||||||
C_SYMBOL_NAME(__mpn_rshift):
|
|
||||||
ld [%o1],%g2 ! load first limb
|
ld [%o1],%g2 ! load first limb
|
||||||
sub %g0,%o3,%o5 ! negate shift count
|
sub %g0,%o3,%o5 ! negate shift count
|
||||||
add %o2,-1,%o2
|
add %o2,-1,%o2
|
||||||
andcc %o2,4-1,%g4 ! number of limbs in first loop
|
andcc %o2,4-1,%g4 ! number of limbs in first loop
|
||||||
sll %g2,%o5,%g1 ! compute function result
|
sll %g2,%o5,%g1 ! compute function result
|
||||||
be L0 ! if multiple of 4 limbs, skip first loop
|
be LOC(0) ! if multiple of 4 limbs, skip first loop
|
||||||
st %g1,[%sp+80]
|
st %g1,[%sp+80]
|
||||||
|
|
||||||
sub %o2,%g4,%o2 ! adjust count for main loop
|
sub %o2,%g4,%o2 ! adjust count for main loop
|
||||||
|
|
||||||
Loop0: ld [%o1+4],%g3
|
LOC(loop0):
|
||||||
|
ld [%o1+4],%g3
|
||||||
add %o0,4,%o0
|
add %o0,4,%o0
|
||||||
add %o1,4,%o1
|
add %o1,4,%o1
|
||||||
addcc %g4,-1,%g4
|
addcc %g4,-1,%g4
|
||||||
@ -50,14 +48,15 @@ Loop0: ld [%o1+4],%g3
|
|||||||
sll %g3,%o5,%g1
|
sll %g3,%o5,%g1
|
||||||
mov %g3,%g2
|
mov %g3,%g2
|
||||||
or %o4,%g1,%o4
|
or %o4,%g1,%o4
|
||||||
bne Loop0
|
bne LOC(loop0)
|
||||||
st %o4,[%o0-4]
|
st %o4,[%o0-4]
|
||||||
|
|
||||||
L0: tst %o2
|
LOC(0): tst %o2
|
||||||
be Lend
|
be LOC(end)
|
||||||
nop
|
nop
|
||||||
|
|
||||||
Loop: ld [%o1+4],%g3
|
LOC(loop):
|
||||||
|
ld [%o1+4],%g3
|
||||||
add %o0,16,%o0
|
add %o0,16,%o0
|
||||||
addcc %o2,-4,%o2
|
addcc %o2,-4,%o2
|
||||||
srl %g2,%o3,%o4
|
srl %g2,%o3,%o4
|
||||||
@ -83,10 +82,13 @@ Loop: ld [%o1+4],%g3
|
|||||||
|
|
||||||
add %o1,16,%o1
|
add %o1,16,%o1
|
||||||
or %g4,%g1,%g4
|
or %g4,%g1,%g4
|
||||||
bne Loop
|
bne LOC(loop)
|
||||||
st %g4,[%o0-4]
|
st %g4,[%o0-4]
|
||||||
|
|
||||||
Lend: srl %g2,%o3,%g2
|
LOC(end):
|
||||||
|
srl %g2,%o3,%g2
|
||||||
st %g2,[%o0-0]
|
st %g2,[%o0-0]
|
||||||
retl
|
retl
|
||||||
ld [%sp+80],%o0
|
ld [%sp+80],%o0
|
||||||
|
|
||||||
|
END(__mpn_rshift)
|
||||||
|
@ -37,22 +37,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
#ifdef __linux__
|
|
||||||
#include <asm/traps.h>
|
|
||||||
#else
|
|
||||||
#ifdef __svr4__
|
|
||||||
#include <sys/trap.h>
|
#include <sys/trap.h>
|
||||||
#else
|
|
||||||
#include <machine/trap.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ENTRY(.div)
|
ENTRY(.div)
|
||||||
! compute sign of result; if neither is negative, no problem
|
! compute sign of result; if neither is negative, no problem
|
||||||
orcc %o1, %o0, %g0 ! either negative?
|
orcc %o1, %o0, %g0 ! either negative?
|
||||||
bge 2f ! no, go do the divide
|
bge 2f ! no, go do the divide
|
||||||
xor %o1, %o0, %g6 ! compute sign in any case
|
xor %o1, %o0, %g3 ! compute sign in any case
|
||||||
tst %o1
|
tst %o1
|
||||||
bge 1f
|
bge 1f
|
||||||
tst %o0
|
tst %o0
|
||||||
@ -76,11 +68,11 @@ ENTRY(.div)
|
|||||||
|
|
||||||
1:
|
1:
|
||||||
cmp %o3, %o5 ! if %o1 exceeds %o0, done
|
cmp %o3, %o5 ! if %o1 exceeds %o0, done
|
||||||
blu Lgot_result ! (and algorithm fails otherwise)
|
blu LOC(got_result) ! (and algorithm fails otherwise)
|
||||||
clr %o2
|
clr %o2
|
||||||
sethi %hi(1 << (32 - 4 - 1)), %g1
|
sethi %hi(1 << (32 - 4 - 1)), %g1
|
||||||
cmp %o3, %g1
|
cmp %o3, %g1
|
||||||
blu Lnot_really_big
|
blu LOC(not_really_big)
|
||||||
clr %o4
|
clr %o4
|
||||||
|
|
||||||
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
||||||
@ -91,15 +83,15 @@ ENTRY(.div)
|
|||||||
1:
|
1:
|
||||||
cmp %o5, %g1
|
cmp %o5, %g1
|
||||||
bgeu 3f
|
bgeu 3f
|
||||||
mov 1, %g7
|
mov 1, %g2
|
||||||
sll %o5, 4, %o5
|
sll %o5, 4, %o5
|
||||||
b 1b
|
b 1b
|
||||||
add %o4, 1, %o4
|
add %o4, 1, %o4
|
||||||
|
|
||||||
! Now compute %g7.
|
! Now compute %g2.
|
||||||
2: addcc %o5, %o5, %o5
|
2: addcc %o5, %o5, %o5
|
||||||
bcc Lnot_too_big
|
bcc LOC(not_too_big)
|
||||||
add %g7, 1, %g7
|
add %g2, 1, %g2
|
||||||
|
|
||||||
! We get here if the %o1 overflowed while shifting.
|
! We get here if the %o1 overflowed while shifting.
|
||||||
! This means that %o3 has the high-order bit set.
|
! This means that %o3 has the high-order bit set.
|
||||||
@ -107,20 +99,20 @@ ENTRY(.div)
|
|||||||
sll %g1, 4, %g1 ! high order bit
|
sll %g1, 4, %g1 ! high order bit
|
||||||
srl %o5, 1, %o5 ! rest of %o5
|
srl %o5, 1, %o5 ! rest of %o5
|
||||||
add %o5, %g1, %o5
|
add %o5, %g1, %o5
|
||||||
b Ldo_single_div
|
b LOC(do_single_div)
|
||||||
sub %g7, 1, %g7
|
sub %g2, 1, %g2
|
||||||
|
|
||||||
Lnot_too_big:
|
LOC(not_too_big):
|
||||||
3: cmp %o5, %o3
|
3: cmp %o5, %o3
|
||||||
blu 2b
|
blu 2b
|
||||||
nop
|
nop
|
||||||
be Ldo_single_div
|
be LOC(do_single_div)
|
||||||
nop
|
nop
|
||||||
/* NB: these are commented out in the V8-Sparc manual as well */
|
/* NB: these are commented out in the V8-Sparc manual as well */
|
||||||
/* (I do not understand this) */
|
/* (I do not understand this) */
|
||||||
! %o5 > %o3: went too far: back up 1 step
|
! %o5 > %o3: went too far: back up 1 step
|
||||||
! srl %o5, 1, %o5
|
! srl %o5, 1, %o5
|
||||||
! dec %g7
|
! dec %g2
|
||||||
! do single-bit divide steps
|
! do single-bit divide steps
|
||||||
!
|
!
|
||||||
! We have to be careful here. We know that %o3 >= %o5, so we can do the
|
! We have to be careful here. We know that %o3 >= %o5, so we can do the
|
||||||
@ -129,15 +121,15 @@ ENTRY(.div)
|
|||||||
! order bit set in the first step, just falling into the regular
|
! order bit set in the first step, just falling into the regular
|
||||||
! division loop will mess up the first time around.
|
! division loop will mess up the first time around.
|
||||||
! So we unroll slightly...
|
! So we unroll slightly...
|
||||||
Ldo_single_div:
|
LOC(do_single_div):
|
||||||
subcc %g7, 1, %g7
|
subcc %g2, 1, %g2
|
||||||
bl Lend_regular_divide
|
bl LOC(end_regular_divide)
|
||||||
nop
|
nop
|
||||||
sub %o3, %o5, %o3
|
sub %o3, %o5, %o3
|
||||||
mov 1, %o2
|
mov 1, %o2
|
||||||
b Lend_single_divloop
|
b LOC(end_single_divloop)
|
||||||
nop
|
nop
|
||||||
Lsingle_divloop:
|
LOC(single_divloop):
|
||||||
sll %o2, 1, %o2
|
sll %o2, 1, %o2
|
||||||
bl 1f
|
bl 1f
|
||||||
srl %o5, 1, %o5
|
srl %o5, 1, %o5
|
||||||
@ -149,221 +141,223 @@ ENTRY(.div)
|
|||||||
add %o3, %o5, %o3
|
add %o3, %o5, %o3
|
||||||
sub %o2, 1, %o2
|
sub %o2, 1, %o2
|
||||||
2:
|
2:
|
||||||
Lend_single_divloop:
|
LOC(end_single_divloop):
|
||||||
subcc %g7, 1, %g7
|
subcc %g2, 1, %g2
|
||||||
bge Lsingle_divloop
|
bge LOC(single_divloop)
|
||||||
tst %o3
|
tst %o3
|
||||||
b,a Lend_regular_divide
|
b,a LOC(end_regular_divide)
|
||||||
|
|
||||||
Lnot_really_big:
|
LOC(not_really_big):
|
||||||
1:
|
1:
|
||||||
sll %o5, 4, %o5
|
sll %o5, 4, %o5
|
||||||
cmp %o5, %o3
|
cmp %o5, %o3
|
||||||
bleu 1b
|
bleu 1b
|
||||||
addcc %o4, 1, %o4
|
addcc %o4, 1, %o4
|
||||||
be Lgot_result
|
be LOC(got_result)
|
||||||
sub %o4, 1, %o4
|
sub %o4, 1, %o4
|
||||||
|
|
||||||
tst %o3 ! set up for initial iteration
|
tst %o3 ! set up for initial iteration
|
||||||
Ldivloop:
|
LOC(divloop):
|
||||||
sll %o2, 4, %o2
|
sll %o2, 4, %o2
|
||||||
! depth 1, accumulated bits 0
|
! depth 1, accumulated bits 0
|
||||||
bl L.1.16
|
bl LOC(1.16)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 2, accumulated bits 1
|
! depth 2, accumulated bits 1
|
||||||
bl L.2.17
|
bl LOC(2.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits 3
|
! depth 3, accumulated bits 3
|
||||||
bl L.3.19
|
bl LOC(3.19)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 7
|
! depth 4, accumulated bits 7
|
||||||
bl L.4.23
|
bl LOC(4.23)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (7*2+1), %o2
|
add %o2, (7*2+1), %o2
|
||||||
|
|
||||||
L.4.23:
|
LOC(4.23):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (7*2-1), %o2
|
add %o2, (7*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.19:
|
LOC(3.19):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 5
|
! depth 4, accumulated bits 5
|
||||||
bl L.4.21
|
bl LOC(4.21)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (5*2+1), %o2
|
add %o2, (5*2+1), %o2
|
||||||
|
|
||||||
L.4.21:
|
LOC(4.21):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (5*2-1), %o2
|
add %o2, (5*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.2.17:
|
LOC(2.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits 1
|
! depth 3, accumulated bits 1
|
||||||
bl L.3.17
|
bl LOC(3.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 3
|
! depth 4, accumulated bits 3
|
||||||
bl L.4.19
|
bl LOC(4.19)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (3*2+1), %o2
|
add %o2, (3*2+1), %o2
|
||||||
|
|
||||||
L.4.19:
|
LOC(4.19):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (3*2-1), %o2
|
add %o2, (3*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.17:
|
LOC(3.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 1
|
! depth 4, accumulated bits 1
|
||||||
bl L.4.17
|
bl LOC(4.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (1*2+1), %o2
|
add %o2, (1*2+1), %o2
|
||||||
|
|
||||||
L.4.17:
|
LOC(4.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (1*2-1), %o2
|
add %o2, (1*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.1.16:
|
LOC(1.16):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 2, accumulated bits -1
|
! depth 2, accumulated bits -1
|
||||||
bl L.2.15
|
bl LOC(2.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits -1
|
! depth 3, accumulated bits -1
|
||||||
bl L.3.15
|
bl LOC(3.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -1
|
! depth 4, accumulated bits -1
|
||||||
bl L.4.15
|
bl LOC(4.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-1*2+1), %o2
|
add %o2, (-1*2+1), %o2
|
||||||
|
|
||||||
L.4.15:
|
LOC(4.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-1*2-1), %o2
|
add %o2, (-1*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.15:
|
LOC(3.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -3
|
! depth 4, accumulated bits -3
|
||||||
bl L.4.13
|
bl LOC(4.13)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-3*2+1), %o2
|
add %o2, (-3*2+1), %o2
|
||||||
|
|
||||||
L.4.13:
|
LOC(4.13):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-3*2-1), %o2
|
add %o2, (-3*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.2.15:
|
LOC(2.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits -3
|
! depth 3, accumulated bits -3
|
||||||
bl L.3.13
|
bl LOC(3.13)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -5
|
! depth 4, accumulated bits -5
|
||||||
bl L.4.11
|
bl LOC(4.11)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-5*2+1), %o2
|
add %o2, (-5*2+1), %o2
|
||||||
|
|
||||||
L.4.11:
|
LOC(4.11):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-5*2-1), %o2
|
add %o2, (-5*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.13:
|
LOC(3.13):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -7
|
! depth 4, accumulated bits -7
|
||||||
bl L.4.9
|
bl LOC(4.9)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-7*2+1), %o2
|
add %o2, (-7*2+1), %o2
|
||||||
|
|
||||||
L.4.9:
|
LOC(4.9):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-7*2-1), %o2
|
add %o2, (-7*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
9:
|
9:
|
||||||
Lend_regular_divide:
|
LOC(end_regular_divide):
|
||||||
subcc %o4, 1, %o4
|
subcc %o4, 1, %o4
|
||||||
bge Ldivloop
|
bge LOC(divloop)
|
||||||
tst %o3
|
tst %o3
|
||||||
bl,a Lgot_result
|
bl,a LOC(got_result)
|
||||||
! non-restoring fixup here (one instruction only!)
|
! non-restoring fixup here (one instruction only!)
|
||||||
sub %o2, 1, %o2
|
sub %o2, 1, %o2
|
||||||
|
|
||||||
|
|
||||||
Lgot_result:
|
LOC(got_result):
|
||||||
! check to see if answer should be < 0
|
! check to see if answer should be < 0
|
||||||
tst %g6
|
tst %g3
|
||||||
bl,a 1f
|
bl,a 1f
|
||||||
sub %g0, %o2, %o2
|
sub %g0, %o2, %o2
|
||||||
1:
|
1:
|
||||||
retl
|
retl
|
||||||
mov %o2, %o0
|
mov %o2, %o0
|
||||||
|
|
||||||
|
END(.div)
|
||||||
|
@ -22,33 +22,29 @@
|
|||||||
#define _ASM 1
|
#define _ASM 1
|
||||||
#include <bits/setjmp.h>
|
#include <bits/setjmp.h>
|
||||||
|
|
||||||
|
ENTRY(_setjmp)
|
||||||
|
b 1f
|
||||||
|
set 0, %o1
|
||||||
|
END(_setjmp)
|
||||||
|
|
||||||
|
ENTRY(setjmp)
|
||||||
|
set 1, %o1
|
||||||
|
END(setjmp)
|
||||||
|
|
||||||
ENTRY (__sigsetjmp)
|
ENTRY (__sigsetjmp)
|
||||||
/* Save our SP and FP; in the delay slot of the jump, save our
|
|
||||||
return PC. Save the signal mask if requested with a tail-call
|
|
||||||
for simplicity; it always returns zero. */
|
|
||||||
ta ST_FLUSH_WINDOWS
|
|
||||||
#ifdef PIC
|
|
||||||
mov %o7,%g1
|
|
||||||
2:
|
|
||||||
call 1f
|
|
||||||
nop
|
|
||||||
1:
|
1:
|
||||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-(2b-.)),%g2
|
/* Save our PC, SP and FP. Save the signal mask if requested with
|
||||||
or %g2,%lo(_GLOBAL_OFFSET_TABLE_-(2b-.)),%g2
|
a tail-call for simplicity; it always returns zero. */
|
||||||
add %g2,%o7,%g2
|
ta ST_FLUSH_WINDOWS
|
||||||
sethi %hi(C_SYMBOL_NAME (__sigjmp_save)), %g3
|
|
||||||
or %g3,%lo(C_SYMBOL_NAME (__sigjmp_save)), %g3
|
st %o7, [%o0 + (JB_PC * 4)]
|
||||||
st %sp, [%o0 + (JB_SP * 4)]
|
st %sp, [%o0 + (JB_SP * 4)]
|
||||||
st %fp, [%o0 + (JB_FP * 4)]
|
st %fp, [%o0 + (JB_FP * 4)]
|
||||||
mov %g1,%o7
|
|
||||||
ld [%g2+%g3],%g1
|
mov %o7, %g1
|
||||||
jmp %g1
|
call __sigjmp_save
|
||||||
st %o7, [%o0+(JB_PC*4)]
|
mov %g1, %o7
|
||||||
#else
|
END(__sigsetjmp)
|
||||||
sethi %hi(C_SYMBOL_NAME (__sigjmp_save)), %g1
|
|
||||||
st %sp, [%o0 + (JB_SP*4)]
|
weak_extern(_setjmp)
|
||||||
or %lo(C_SYMBOL_NAME (__sigjmp_save)), %g1, %g1
|
weak_extern(setjmp)
|
||||||
st %fp, [%o0 + (JB_FP*4)]
|
|
||||||
jmp %g1
|
|
||||||
st %o7, [%o0 + (JB_PC*4)]
|
|
||||||
#endif /* PIC */
|
|
||||||
|
@ -27,54 +27,52 @@
|
|||||||
! size o2
|
! size o2
|
||||||
! s2_limb o3
|
! s2_limb o3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_addmul_1)
|
||||||
.align 4
|
|
||||||
.global C_SYMBOL_NAME(__mpn_addmul_1)
|
|
||||||
C_SYMBOL_NAME(__mpn_addmul_1):
|
|
||||||
orcc %g0,%g0,%g2
|
|
||||||
ld [%o1+0],%o4 ! 1
|
ld [%o1+0],%o4 ! 1
|
||||||
|
|
||||||
sll %o2,4,%g1
|
sll %o2,4,%g1
|
||||||
and %g1,(4-1)<<4,%g1
|
orcc %g0,%g0,%g2
|
||||||
#if PIC
|
|
||||||
mov %o7,%g4 ! Save return address register
|
mov %o7,%g4 ! Save return address register
|
||||||
call 1f
|
and %g1,(4-1)<<4,%g1
|
||||||
add %o7,LL-1f,%g3
|
1: call 2f
|
||||||
1: mov %g4,%o7 ! Restore return address register
|
add %o7,3f-1b,%g3
|
||||||
#else
|
2: jmp %g3+%g1
|
||||||
sethi %hi(LL),%g3
|
mov %g4,%o7 ! Restore return address register
|
||||||
or %g3,%lo(LL),%g3
|
|
||||||
#endif
|
.align 4
|
||||||
jmp %g3+%g1
|
3:
|
||||||
|
LOC(00):
|
||||||
|
add %o0,-4,%o0
|
||||||
|
b LOC(loop00) /* 4, 8, 12, ... */
|
||||||
|
add %o1,-4,%o1
|
||||||
nop
|
nop
|
||||||
LL:
|
LOC(01):
|
||||||
LL00: add %o0,-4,%o0
|
b LOC(loop01) /* 1, 5, 9, ... */
|
||||||
b Loop00 /* 4, 8, 12, ... */
|
nop
|
||||||
add %o1,-4,%o1
|
|
||||||
nop
|
|
||||||
LL01: b Loop01 /* 1, 5, 9, ... */
|
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
|
LOC(10):
|
||||||
|
add %o0,-12,%o0 /* 2, 6, 10, ... */
|
||||||
|
b LOC(loop10)
|
||||||
|
add %o1,4,%o1
|
||||||
nop
|
nop
|
||||||
LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
|
LOC(11):
|
||||||
b Loop10
|
add %o0,-8,%o0 /* 3, 7, 11, ... */
|
||||||
add %o1,4,%o1
|
b LOC(loop11)
|
||||||
nop
|
add %o1,-8,%o1
|
||||||
LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
|
|
||||||
b Loop11
|
|
||||||
add %o1,-8,%o1
|
|
||||||
nop
|
nop
|
||||||
|
|
||||||
1: addcc %g3,%g2,%g3 ! 1
|
LOC(loop):
|
||||||
|
addcc %g3,%g2,%g3 ! 1
|
||||||
ld [%o1+4],%o4 ! 2
|
ld [%o1+4],%o4 ! 2
|
||||||
rd %y,%g2 ! 1
|
rd %y,%g2 ! 1
|
||||||
addx %g0,%g2,%g2
|
addx %g0,%g2,%g2
|
||||||
ld [%o0+0],%g1 ! 2
|
ld [%o0+0],%g1 ! 2
|
||||||
addcc %g1,%g3,%g3
|
addcc %g1,%g3,%g3
|
||||||
st %g3,[%o0+0] ! 1
|
st %g3,[%o0+0] ! 1
|
||||||
Loop00: umul %o4,%o3,%g3 ! 2
|
LOC(loop00):
|
||||||
|
umul %o4,%o3,%g3 ! 2
|
||||||
ld [%o0+4],%g1 ! 2
|
ld [%o0+4],%g1 ! 2
|
||||||
addxcc %g3,%g2,%g3 ! 2
|
addxcc %g3,%g2,%g3 ! 2
|
||||||
ld [%o1+8],%o4 ! 3
|
ld [%o1+8],%o4 ! 3
|
||||||
@ -83,7 +81,8 @@ Loop00: umul %o4,%o3,%g3 ! 2
|
|||||||
nop
|
nop
|
||||||
addcc %g1,%g3,%g3
|
addcc %g1,%g3,%g3
|
||||||
st %g3,[%o0+4] ! 2
|
st %g3,[%o0+4] ! 2
|
||||||
Loop11: umul %o4,%o3,%g3 ! 3
|
LOC(loop11):
|
||||||
|
umul %o4,%o3,%g3 ! 3
|
||||||
addxcc %g3,%g2,%g3 ! 3
|
addxcc %g3,%g2,%g3 ! 3
|
||||||
ld [%o1+12],%o4 ! 4
|
ld [%o1+12],%o4 ! 4
|
||||||
rd %y,%g2 ! 3
|
rd %y,%g2 ! 3
|
||||||
@ -92,7 +91,8 @@ Loop11: umul %o4,%o3,%g3 ! 3
|
|||||||
ld [%o0+8],%g1 ! 2
|
ld [%o0+8],%g1 ! 2
|
||||||
addcc %g1,%g3,%g3
|
addcc %g1,%g3,%g3
|
||||||
st %g3,[%o0+8] ! 3
|
st %g3,[%o0+8] ! 3
|
||||||
Loop10: umul %o4,%o3,%g3 ! 4
|
LOC(loop10):
|
||||||
|
umul %o4,%o3,%g3 ! 4
|
||||||
addxcc %g3,%g2,%g3 ! 4
|
addxcc %g3,%g2,%g3 ! 4
|
||||||
ld [%o1+0],%o4 ! 1
|
ld [%o1+0],%o4 ! 1
|
||||||
rd %y,%g2 ! 4
|
rd %y,%g2 ! 4
|
||||||
@ -102,9 +102,10 @@ Loop10: umul %o4,%o3,%g3 ! 4
|
|||||||
st %g3,[%o0+12] ! 4
|
st %g3,[%o0+12] ! 4
|
||||||
add %o0,16,%o0
|
add %o0,16,%o0
|
||||||
addx %g0,%g2,%g2
|
addx %g0,%g2,%g2
|
||||||
Loop01: addcc %o2,-4,%o2
|
LOC(loop01):
|
||||||
bg 1b
|
addcc %o2,-4,%o2
|
||||||
umul %o4,%o3,%g3 ! 1
|
bg LOC(loop)
|
||||||
|
umul %o4,%o3,%g3 ! 1
|
||||||
|
|
||||||
addcc %g3,%g2,%g3 ! 4
|
addcc %g3,%g2,%g3 ! 4
|
||||||
rd %y,%g2 ! 4
|
rd %y,%g2 ! 4
|
||||||
@ -112,13 +113,7 @@ Loop01: addcc %o2,-4,%o2
|
|||||||
ld [%o0+0],%g1 ! 2
|
ld [%o0+0],%g1 ! 2
|
||||||
addcc %g1,%g3,%g3
|
addcc %g1,%g3,%g3
|
||||||
st %g3,[%o0+0] ! 4
|
st %g3,[%o0+0] ! 4
|
||||||
addx %g0,%g2,%o0
|
|
||||||
|
|
||||||
retl
|
retl
|
||||||
nop
|
addx %g0,%g2,%o0
|
||||||
|
|
||||||
|
|
||||||
! umul, ld, addxcc, rd, st
|
|
||||||
|
|
||||||
! umul, ld, addxcc, rd, ld, addcc, st, addx
|
|
||||||
|
|
||||||
|
END(__mpn_addmul_1)
|
||||||
|
13
sysdeps/sparc/sparc32/sparcv8/dotmul.S
Normal file
13
sysdeps/sparc/sparc32/sparcv8/dotmul.S
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Sparc v8 has multiply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
ENTRY(.mul)
|
||||||
|
|
||||||
|
smul %o0, %o1, %o0
|
||||||
|
retl
|
||||||
|
rd %y, %o1
|
||||||
|
|
||||||
|
END(.mul)
|
@ -27,73 +27,77 @@
|
|||||||
! size o2
|
! size o2
|
||||||
! s2_limb o3
|
! s2_limb o3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_mul_1)
|
||||||
.align 8
|
|
||||||
.global C_SYMBOL_NAME(__mpn_mul_1)
|
|
||||||
C_SYMBOL_NAME(__mpn_mul_1):
|
|
||||||
sll %o2,4,%g1
|
sll %o2,4,%g1
|
||||||
and %g1,(4-1)<<4,%g1
|
|
||||||
#if PIC
|
|
||||||
mov %o7,%g4 ! Save return address register
|
mov %o7,%g4 ! Save return address register
|
||||||
call 1f
|
and %g1,(4-1)<<4,%g1
|
||||||
add %o7,LL-1f,%g3
|
1: call 2f
|
||||||
1: mov %g4,%o7 ! Restore return address register
|
add %o7,3f-1b,%g3
|
||||||
#else
|
2: mov %g4,%o7 ! Restore return address register
|
||||||
sethi %hi(LL),%g3
|
|
||||||
or %g3,%lo(LL),%g3
|
|
||||||
#endif
|
|
||||||
jmp %g3+%g1
|
jmp %g3+%g1
|
||||||
ld [%o1+0],%o4 ! 1
|
ld [%o1+0],%o4 ! 1
|
||||||
LL:
|
|
||||||
LL00: add %o0,-4,%o0
|
|
||||||
add %o1,-4,%o1
|
|
||||||
b Loop00 /* 4, 8, 12, ... */
|
|
||||||
orcc %g0,%g0,%g2
|
|
||||||
LL01: b Loop01 /* 1, 5, 9, ... */
|
|
||||||
orcc %g0,%g0,%g2
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
|
|
||||||
add %o1,4,%o1
|
|
||||||
b Loop10
|
|
||||||
orcc %g0,%g0,%g2
|
|
||||||
nop
|
|
||||||
LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
|
|
||||||
add %o1,-8,%o1
|
|
||||||
b Loop11
|
|
||||||
orcc %g0,%g0,%g2
|
|
||||||
|
|
||||||
Loop: addcc %g3,%g2,%g3 ! 1
|
.align 4
|
||||||
|
3:
|
||||||
|
LOC(00):
|
||||||
|
add %o0,-4,%o0
|
||||||
|
add %o1,-4,%o1
|
||||||
|
b LOC(loop00) /* 4, 8, 12, ... */
|
||||||
|
orcc %g0,%g0,%g2
|
||||||
|
LOC(01):
|
||||||
|
b LOC(loop01) /* 1, 5, 9, ... */
|
||||||
|
orcc %g0,%g0,%g2
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
LOC(10):
|
||||||
|
add %o0,-12,%o0 /* 2, 6, 10, ... */
|
||||||
|
add %o1,4,%o1
|
||||||
|
b LOC(loop10)
|
||||||
|
orcc %g0,%g0,%g2
|
||||||
|
nop
|
||||||
|
LOC(11):
|
||||||
|
add %o0,-8,%o0 /* 3, 7, 11, ... */
|
||||||
|
add %o1,-8,%o1
|
||||||
|
b LOC(loop11)
|
||||||
|
orcc %g0,%g0,%g2
|
||||||
|
|
||||||
|
LOC(loop):
|
||||||
|
addcc %g3,%g2,%g3 ! 1
|
||||||
ld [%o1+4],%o4 ! 2
|
ld [%o1+4],%o4 ! 2
|
||||||
st %g3,[%o0+0] ! 1
|
st %g3,[%o0+0] ! 1
|
||||||
rd %y,%g2 ! 1
|
rd %y,%g2 ! 1
|
||||||
Loop00: umul %o4,%o3,%g3 ! 2
|
LOC(loop00):
|
||||||
|
umul %o4,%o3,%g3 ! 2
|
||||||
addxcc %g3,%g2,%g3 ! 2
|
addxcc %g3,%g2,%g3 ! 2
|
||||||
ld [%o1+8],%o4 ! 3
|
ld [%o1+8],%o4 ! 3
|
||||||
st %g3,[%o0+4] ! 2
|
st %g3,[%o0+4] ! 2
|
||||||
rd %y,%g2 ! 2
|
rd %y,%g2 ! 2
|
||||||
Loop11: umul %o4,%o3,%g3 ! 3
|
LOC(loop11):
|
||||||
|
umul %o4,%o3,%g3 ! 3
|
||||||
addxcc %g3,%g2,%g3 ! 3
|
addxcc %g3,%g2,%g3 ! 3
|
||||||
ld [%o1+12],%o4 ! 4
|
ld [%o1+12],%o4 ! 4
|
||||||
add %o1,16,%o1
|
add %o1,16,%o1
|
||||||
st %g3,[%o0+8] ! 3
|
st %g3,[%o0+8] ! 3
|
||||||
rd %y,%g2 ! 3
|
rd %y,%g2 ! 3
|
||||||
Loop10: umul %o4,%o3,%g3 ! 4
|
LOC(loop10):
|
||||||
|
umul %o4,%o3,%g3 ! 4
|
||||||
addxcc %g3,%g2,%g3 ! 4
|
addxcc %g3,%g2,%g3 ! 4
|
||||||
ld [%o1+0],%o4 ! 1
|
ld [%o1+0],%o4 ! 1
|
||||||
st %g3,[%o0+12] ! 4
|
st %g3,[%o0+12] ! 4
|
||||||
add %o0,16,%o0
|
add %o0,16,%o0
|
||||||
rd %y,%g2 ! 4
|
rd %y,%g2 ! 4
|
||||||
addx %g0,%g2,%g2
|
addx %g0,%g2,%g2
|
||||||
Loop01: addcc %o2,-4,%o2
|
LOC(loop01):
|
||||||
bg Loop
|
addcc %o2,-4,%o2
|
||||||
umul %o4,%o3,%g3 ! 1
|
bg LOC(loop)
|
||||||
|
umul %o4,%o3,%g3 ! 1
|
||||||
|
|
||||||
addcc %g3,%g2,%g3 ! 4
|
addcc %g3,%g2,%g3 ! 4
|
||||||
st %g3,[%o0+0] ! 4
|
st %g3,[%o0+0] ! 4
|
||||||
rd %y,%g2 ! 4
|
rd %y,%g2 ! 4
|
||||||
|
|
||||||
retl
|
retl
|
||||||
addx %g0,%g2,%o0
|
addx %g0,%g2,%o0
|
||||||
|
|
||||||
|
END(__mpn_mul_1)
|
||||||
|
18
sysdeps/sparc/sparc32/sparcv8/rem.S
Normal file
18
sysdeps/sparc/sparc32/sparcv8/rem.S
Normal 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)
|
14
sysdeps/sparc/sparc32/sparcv8/sdiv.S
Normal file
14
sysdeps/sparc/sparc32/sparcv8/sdiv.S
Normal 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)
|
@ -27,12 +27,9 @@
|
|||||||
! size o2
|
! size o2
|
||||||
! s2_limb o3
|
! s2_limb o3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_submul_1)
|
||||||
.align 4
|
|
||||||
.global C_SYMBOL_NAME(__mpn_submul_1)
|
|
||||||
C_SYMBOL_NAME(__mpn_submul_1):
|
|
||||||
sub %g0,%o2,%o2 ! negate ...
|
sub %g0,%o2,%o2 ! negate ...
|
||||||
sll %o2,2,%o2 ! ... and scale size
|
sll %o2,2,%o2 ! ... and scale size
|
||||||
sub %o1,%o2,%o1 ! o1 is offset s1_ptr
|
sub %o1,%o2,%o1 ! o1 is offset s1_ptr
|
||||||
@ -40,7 +37,8 @@ C_SYMBOL_NAME(__mpn_submul_1):
|
|||||||
|
|
||||||
mov 0,%o0 ! clear cy_limb
|
mov 0,%o0 ! clear cy_limb
|
||||||
|
|
||||||
Loop: ld [%o1+%o2],%o4
|
LOC(loop):
|
||||||
|
ld [%o1+%o2],%o4
|
||||||
ld [%g1+%o2],%g2
|
ld [%g1+%o2],%g2
|
||||||
umul %o4,%o3,%o5
|
umul %o4,%o3,%o5
|
||||||
rd %y,%g3
|
rd %y,%g3
|
||||||
@ -51,8 +49,10 @@ Loop: ld [%o1+%o2],%o4
|
|||||||
st %g2,[%g1+%o2]
|
st %g2,[%g1+%o2]
|
||||||
|
|
||||||
addcc %o2,4,%o2
|
addcc %o2,4,%o2
|
||||||
bne Loop
|
bne LOC(loop)
|
||||||
nop
|
nop
|
||||||
|
|
||||||
retl
|
retl
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
END(__mpn_submul_1)
|
||||||
|
13
sysdeps/sparc/sparc32/sparcv8/udiv.S
Normal file
13
sysdeps/sparc/sparc32/sparcv8/udiv.S
Normal 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)
|
@ -27,66 +27,75 @@
|
|||||||
|
|
||||||
#include "sysdep.h"
|
#include "sysdep.h"
|
||||||
|
|
||||||
.text
|
ENTRY(__udiv_qrnnd)
|
||||||
.align 4
|
|
||||||
.global C_SYMBOL_NAME(__udiv_qrnnd)
|
|
||||||
C_SYMBOL_NAME(__udiv_qrnnd):
|
|
||||||
tst %o3
|
tst %o3
|
||||||
bneg Largedivisor
|
bneg LOC(largedivisor)
|
||||||
mov 8,%g1
|
mov 8,%g1
|
||||||
|
|
||||||
b Lp1
|
b LOC(p1)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
|
|
||||||
Lplop: bcc Ln1
|
LOC(plop):
|
||||||
|
bcc LOC(n1)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Lp1: addx %o1,%o1,%o1
|
LOC(p1):
|
||||||
|
addx %o1,%o1,%o1
|
||||||
subcc %o1,%o3,%o4
|
subcc %o1,%o3,%o4
|
||||||
bcc Ln2
|
bcc LOC(n2)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Lp2: addx %o1,%o1,%o1
|
LOC(p2):
|
||||||
|
addx %o1,%o1,%o1
|
||||||
subcc %o1,%o3,%o4
|
subcc %o1,%o3,%o4
|
||||||
bcc Ln3
|
bcc LOC(n3)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Lp3: addx %o1,%o1,%o1
|
LOC(p3):
|
||||||
|
addx %o1,%o1,%o1
|
||||||
subcc %o1,%o3,%o4
|
subcc %o1,%o3,%o4
|
||||||
bcc Ln4
|
bcc LOC(n4)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Lp4: addx %o1,%o1,%o1
|
LOC(p4):
|
||||||
|
addx %o1,%o1,%o1
|
||||||
addcc %g1,-1,%g1
|
addcc %g1,-1,%g1
|
||||||
bne Lplop
|
bne LOC(plop)
|
||||||
subcc %o1,%o3,%o4
|
subcc %o1,%o3,%o4
|
||||||
bcc Ln5
|
bcc LOC(n5)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Lp5: st %o1,[%o0]
|
LOC(p5):
|
||||||
|
st %o1,[%o0]
|
||||||
retl
|
retl
|
||||||
xnor %g0,%o2,%o0
|
xnor %g0,%o2,%o0
|
||||||
|
|
||||||
Lnlop: bcc Lp1
|
LOC(nlop):
|
||||||
|
bcc LOC(p1)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Ln1: addx %o4,%o4,%o4
|
LOC(n1):
|
||||||
|
addx %o4,%o4,%o4
|
||||||
subcc %o4,%o3,%o1
|
subcc %o4,%o3,%o1
|
||||||
bcc Lp2
|
bcc LOC(p2)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Ln2: addx %o4,%o4,%o4
|
LOC(n2):
|
||||||
|
addx %o4,%o4,%o4
|
||||||
subcc %o4,%o3,%o1
|
subcc %o4,%o3,%o1
|
||||||
bcc Lp3
|
bcc LOC(p3)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Ln3: addx %o4,%o4,%o4
|
LOC(n3):
|
||||||
|
addx %o4,%o4,%o4
|
||||||
subcc %o4,%o3,%o1
|
subcc %o4,%o3,%o1
|
||||||
bcc Lp4
|
bcc LOC(p4)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Ln4: addx %o4,%o4,%o4
|
LOC(n4):
|
||||||
|
addx %o4,%o4,%o4
|
||||||
addcc %g1,-1,%g1
|
addcc %g1,-1,%g1
|
||||||
bne Lnlop
|
bne LOC(nlop)
|
||||||
subcc %o4,%o3,%o1
|
subcc %o4,%o3,%o1
|
||||||
bcc Lp5
|
bcc LOC(p5)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
Ln5: st %o4,[%o0]
|
LOC(n5):
|
||||||
|
st %o4,[%o0]
|
||||||
retl
|
retl
|
||||||
xnor %g0,%o2,%o0
|
xnor %g0,%o2,%o0
|
||||||
|
|
||||||
Largedivisor:
|
LOC(largedivisor):
|
||||||
and %o2,1,%o5 ! %o5 = n0 & 1
|
and %o2,1,%o5 ! %o5 = n0 & 1
|
||||||
|
|
||||||
srl %o2,1,%o2
|
srl %o2,1,%o2
|
||||||
@ -98,89 +107,109 @@ Largedivisor:
|
|||||||
srl %o3,1,%g3 ! %g3 = floor(d / 2)
|
srl %o3,1,%g3 ! %g3 = floor(d / 2)
|
||||||
add %g3,%g2,%g3 ! %g3 = ceil(d / 2)
|
add %g3,%g2,%g3 ! %g3 = ceil(d / 2)
|
||||||
|
|
||||||
b LLp1
|
b LOC(Lp1)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
|
|
||||||
LLplop: bcc LLn1
|
LOC(Lplop):
|
||||||
|
bcc LOC(Ln1)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLp1: addx %o1,%o1,%o1
|
LOC(Lp1):
|
||||||
|
addx %o1,%o1,%o1
|
||||||
subcc %o1,%g3,%o4
|
subcc %o1,%g3,%o4
|
||||||
bcc LLn2
|
bcc LOC(Ln2)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLp2: addx %o1,%o1,%o1
|
LOC(Lp2):
|
||||||
|
addx %o1,%o1,%o1
|
||||||
subcc %o1,%g3,%o4
|
subcc %o1,%g3,%o4
|
||||||
bcc LLn3
|
bcc LOC(Ln3)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLp3: addx %o1,%o1,%o1
|
LOC(Lp3):
|
||||||
|
addx %o1,%o1,%o1
|
||||||
subcc %o1,%g3,%o4
|
subcc %o1,%g3,%o4
|
||||||
bcc LLn4
|
bcc LOC(Ln4)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLp4: addx %o1,%o1,%o1
|
LOC(Lp4):
|
||||||
|
addx %o1,%o1,%o1
|
||||||
addcc %g1,-1,%g1
|
addcc %g1,-1,%g1
|
||||||
bne LLplop
|
bne LOC(Lplop)
|
||||||
subcc %o1,%g3,%o4
|
subcc %o1,%g3,%o4
|
||||||
bcc LLn5
|
bcc LOC(Ln5)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLp5: add %o1,%o1,%o1 ! << 1
|
LOC(Lp5):
|
||||||
|
add %o1,%o1,%o1 ! << 1
|
||||||
tst %g2
|
tst %g2
|
||||||
bne Oddp
|
bne LOC(Oddp)
|
||||||
add %o5,%o1,%o1
|
add %o5,%o1,%o1
|
||||||
st %o1,[%o0]
|
st %o1,[%o0]
|
||||||
retl
|
retl
|
||||||
xnor %g0,%o2,%o0
|
xnor %g0,%o2,%o0
|
||||||
|
|
||||||
LLnlop: bcc LLp1
|
LOC(Lnlop):
|
||||||
|
bcc LOC(Lp1)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLn1: addx %o4,%o4,%o4
|
LOC(Ln1):
|
||||||
|
addx %o4,%o4,%o4
|
||||||
subcc %o4,%g3,%o1
|
subcc %o4,%g3,%o1
|
||||||
bcc LLp2
|
bcc LOC(Lp2)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLn2: addx %o4,%o4,%o4
|
LOC(Ln2):
|
||||||
|
addx %o4,%o4,%o4
|
||||||
subcc %o4,%g3,%o1
|
subcc %o4,%g3,%o1
|
||||||
bcc LLp3
|
bcc LOC(Lp3)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLn3: addx %o4,%o4,%o4
|
LOC(Ln3):
|
||||||
|
addx %o4,%o4,%o4
|
||||||
subcc %o4,%g3,%o1
|
subcc %o4,%g3,%o1
|
||||||
bcc LLp4
|
bcc LOC(Lp4)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLn4: addx %o4,%o4,%o4
|
LOC(Ln4):
|
||||||
|
addx %o4,%o4,%o4
|
||||||
addcc %g1,-1,%g1
|
addcc %g1,-1,%g1
|
||||||
bne LLnlop
|
bne LOC(Lnlop)
|
||||||
subcc %o4,%g3,%o1
|
subcc %o4,%g3,%o1
|
||||||
bcc LLp5
|
bcc LOC(Lp5)
|
||||||
addxcc %o2,%o2,%o2
|
addxcc %o2,%o2,%o2
|
||||||
LLn5: add %o4,%o4,%o4 ! << 1
|
LOC(Ln5):
|
||||||
|
add %o4,%o4,%o4 ! << 1
|
||||||
tst %g2
|
tst %g2
|
||||||
bne Oddn
|
bne LOC(Oddn)
|
||||||
add %o5,%o4,%o4
|
add %o5,%o4,%o4
|
||||||
st %o4,[%o0]
|
st %o4,[%o0]
|
||||||
retl
|
retl
|
||||||
xnor %g0,%o2,%o0
|
xnor %g0,%o2,%o0
|
||||||
|
|
||||||
Oddp: xnor %g0,%o2,%o2
|
LOC(Oddp):
|
||||||
|
xnor %g0,%o2,%o2
|
||||||
! q' in %o2. r' in %o1
|
! q' in %o2. r' in %o1
|
||||||
addcc %o1,%o2,%o1
|
addcc %o1,%o2,%o1
|
||||||
bcc LLp6
|
bcc LOC(Lp6)
|
||||||
addx %o2,0,%o2
|
addx %o2,0,%o2
|
||||||
sub %o1,%o3,%o1
|
sub %o1,%o3,%o1
|
||||||
LLp6: subcc %o1,%o3,%g0
|
LOC(Lp6):
|
||||||
bcs LLp7
|
subcc %o1,%o3,%g0
|
||||||
|
bcs LOC(Lp7)
|
||||||
subx %o2,-1,%o2
|
subx %o2,-1,%o2
|
||||||
sub %o1,%o3,%o1
|
sub %o1,%o3,%o1
|
||||||
LLp7: st %o1,[%o0]
|
LOC(Lp7):
|
||||||
|
st %o1,[%o0]
|
||||||
retl
|
retl
|
||||||
mov %o2,%o0
|
mov %o2,%o0
|
||||||
|
|
||||||
Oddn: xnor %g0,%o2,%o2
|
LOC(Oddn):
|
||||||
|
xnor %g0,%o2,%o2
|
||||||
! q' in %o2. r' in %o4
|
! q' in %o2. r' in %o4
|
||||||
addcc %o4,%o2,%o4
|
addcc %o4,%o2,%o4
|
||||||
bcc LLn6
|
bcc LOC(Ln6)
|
||||||
addx %o2,0,%o2
|
addx %o2,0,%o2
|
||||||
sub %o4,%o3,%o4
|
sub %o4,%o3,%o4
|
||||||
LLn6: subcc %o4,%o3,%g0
|
LOC(Ln6):
|
||||||
bcs LLn7
|
subcc %o4,%o3,%g0
|
||||||
|
bcs LOC(Ln7)
|
||||||
subx %o2,-1,%o2
|
subx %o2,-1,%o2
|
||||||
sub %o4,%o3,%o4
|
sub %o4,%o3,%o4
|
||||||
LLn7: st %o4,[%o0]
|
LOC(Ln7):
|
||||||
|
st %o4,[%o0]
|
||||||
retl
|
retl
|
||||||
mov %o2,%o0
|
mov %o2,%o0
|
||||||
|
|
||||||
|
END(__udiv_qrnnd)
|
||||||
|
13
sysdeps/sparc/sparc32/sparcv8/umul.S
Normal file
13
sysdeps/sparc/sparc32/sparcv8/umul.S
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Sparc v8 has multiply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
ENTRY(.umul)
|
||||||
|
|
||||||
|
umul %o0, %o1, %o0
|
||||||
|
retl
|
||||||
|
rd %y, %o1
|
||||||
|
|
||||||
|
END(.umul)
|
15
sysdeps/sparc/sparc32/sparcv8/urem.S
Normal file
15
sysdeps/sparc/sparc32/sparcv8/urem.S
Normal 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)
|
@ -1,20 +1,20 @@
|
|||||||
! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
|
! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
|
||||||
! store difference in a third limb vector.
|
! store difference in a third limb vector.
|
||||||
|
!
|
||||||
! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||||
|
!
|
||||||
! This file is part of the GNU MP Library.
|
! This file is part of the GNU MP Library.
|
||||||
|
!
|
||||||
! The GNU MP Library is free software; you can redistribute it and/or modify
|
! The GNU MP Library is free software; you can redistribute it and/or modify
|
||||||
! it under the terms of the GNU Library General Public License as published by
|
! it under the terms of the GNU Library General Public License as published by
|
||||||
! the Free Software Foundation; either version 2 of the License, or (at your
|
! the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
! option) any later version.
|
! option) any later version.
|
||||||
|
!
|
||||||
! The GNU MP Library is distributed in the hope that it will be useful, but
|
! The GNU MP Library is distributed in the hope that it will be useful, but
|
||||||
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
! License for more details.
|
! License for more details.
|
||||||
|
!
|
||||||
! You should have received a copy of the GNU Library General Public License
|
! You should have received a copy of the GNU Library General Public License
|
||||||
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||||
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
@ -22,290 +22,308 @@
|
|||||||
|
|
||||||
|
|
||||||
! INPUT PARAMETERS
|
! INPUT PARAMETERS
|
||||||
#define res_ptr %o0
|
#define RES_PTR %o0
|
||||||
#define s1_ptr %o1
|
#define S1_PTR %o1
|
||||||
#define s2_ptr %o2
|
#define S2_PTR %o2
|
||||||
#define size %o3
|
#define SIZE %o3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_sub_n)
|
||||||
.align 4
|
xor S2_PTR,RES_PTR,%g1
|
||||||
.global C_SYMBOL_NAME(__mpn_sub_n)
|
|
||||||
C_SYMBOL_NAME(__mpn_sub_n):
|
|
||||||
xor s2_ptr,res_ptr,%g1
|
|
||||||
andcc %g1,4,%g0
|
andcc %g1,4,%g0
|
||||||
bne L1 ! branch if alignment differs
|
bne LOC(1) ! branch if alignment differs
|
||||||
nop
|
nop
|
||||||
! ** V1a **
|
! ** V1a **
|
||||||
andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
|
andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
|
||||||
be L_v1 ! if no, branch
|
be LOC(v1) ! if no, branch
|
||||||
nop
|
nop
|
||||||
/* Add least significant limb separately to align res_ptr and s2_ptr */
|
/* Add least significant limb separately to align RES_PTR and S2_PTR */
|
||||||
ld [s1_ptr],%g4
|
ld [S1_PTR],%g4
|
||||||
add s1_ptr,4,s1_ptr
|
add S1_PTR,4,S1_PTR
|
||||||
ld [s2_ptr],%g2
|
ld [S2_PTR],%g2
|
||||||
add s2_ptr,4,s2_ptr
|
add S2_PTR,4,S2_PTR
|
||||||
add size,-1,size
|
add SIZE,-1,SIZE
|
||||||
subcc %g4,%g2,%o4
|
subcc %g4,%g2,%o4
|
||||||
st %o4,[res_ptr]
|
st %o4,[RES_PTR]
|
||||||
add res_ptr,4,res_ptr
|
add RES_PTR,4,RES_PTR
|
||||||
L_v1: addx %g0,%g0,%o4 ! save cy in register
|
LOC(v1):
|
||||||
cmp size,2 ! if size < 2 ...
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
bl Lend2 ! ... branch to tail code
|
cmp SIZE,2 ! if SIZE < 2 ...
|
||||||
|
bl LOC(end2) ! ... branch to tail code
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
|
|
||||||
ld [s1_ptr+0],%g4
|
ld [S1_PTR+0],%g4
|
||||||
addcc size,-10,size
|
addcc SIZE,-10,SIZE
|
||||||
ld [s1_ptr+4],%g1
|
ld [S1_PTR+4],%g1
|
||||||
ldd [s2_ptr+0],%g2
|
ldd [S2_PTR+0],%g2
|
||||||
blt Lfin1
|
blt LOC(fin1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||||
Loop1: subxcc %g4,%g2,%o4
|
LOC(loop1):
|
||||||
ld [s1_ptr+8],%g4
|
|
||||||
subxcc %g1,%g3,%o5
|
|
||||||
ld [s1_ptr+12],%g1
|
|
||||||
ldd [s2_ptr+8],%g2
|
|
||||||
std %o4,[res_ptr+0]
|
|
||||||
subxcc %g4,%g2,%o4
|
subxcc %g4,%g2,%o4
|
||||||
ld [s1_ptr+16],%g4
|
ld [S1_PTR+8],%g4
|
||||||
subxcc %g1,%g3,%o5
|
subxcc %g1,%g3,%o5
|
||||||
ld [s1_ptr+20],%g1
|
ld [S1_PTR+12],%g1
|
||||||
ldd [s2_ptr+16],%g2
|
ldd [S2_PTR+8],%g2
|
||||||
std %o4,[res_ptr+8]
|
std %o4,[RES_PTR+0]
|
||||||
subxcc %g4,%g2,%o4
|
subxcc %g4,%g2,%o4
|
||||||
ld [s1_ptr+24],%g4
|
ld [S1_PTR+16],%g4
|
||||||
subxcc %g1,%g3,%o5
|
subxcc %g1,%g3,%o5
|
||||||
ld [s1_ptr+28],%g1
|
ld [S1_PTR+20],%g1
|
||||||
ldd [s2_ptr+24],%g2
|
ldd [S2_PTR+16],%g2
|
||||||
std %o4,[res_ptr+16]
|
std %o4,[RES_PTR+8]
|
||||||
subxcc %g4,%g2,%o4
|
subxcc %g4,%g2,%o4
|
||||||
ld [s1_ptr+32],%g4
|
ld [S1_PTR+24],%g4
|
||||||
subxcc %g1,%g3,%o5
|
subxcc %g1,%g3,%o5
|
||||||
ld [s1_ptr+36],%g1
|
ld [S1_PTR+28],%g1
|
||||||
ldd [s2_ptr+32],%g2
|
ldd [S2_PTR+24],%g2
|
||||||
std %o4,[res_ptr+24]
|
std %o4,[RES_PTR+16]
|
||||||
|
subxcc %g4,%g2,%o4
|
||||||
|
ld [S1_PTR+32],%g4
|
||||||
|
subxcc %g1,%g3,%o5
|
||||||
|
ld [S1_PTR+36],%g1
|
||||||
|
ldd [S2_PTR+32],%g2
|
||||||
|
std %o4,[RES_PTR+24]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-8,size
|
addcc SIZE,-8,SIZE
|
||||||
add s1_ptr,32,s1_ptr
|
add S1_PTR,32,S1_PTR
|
||||||
add s2_ptr,32,s2_ptr
|
add S2_PTR,32,S2_PTR
|
||||||
add res_ptr,32,res_ptr
|
add RES_PTR,32,RES_PTR
|
||||||
bge Loop1
|
bge LOC(loop1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
|
|
||||||
Lfin1: addcc size,8-2,size
|
LOC(fin1):
|
||||||
blt Lend1
|
addcc SIZE,8-2,SIZE
|
||||||
|
blt LOC(end1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add blocks of 2 limbs until less than 2 limbs remain */
|
/* Add blocks of 2 limbs until less than 2 limbs remain */
|
||||||
Loope1: subxcc %g4,%g2,%o4
|
LOC(loope1):
|
||||||
ld [s1_ptr+8],%g4
|
subxcc %g4,%g2,%o4
|
||||||
|
ld [S1_PTR+8],%g4
|
||||||
subxcc %g1,%g3,%o5
|
subxcc %g1,%g3,%o5
|
||||||
ld [s1_ptr+12],%g1
|
ld [S1_PTR+12],%g1
|
||||||
ldd [s2_ptr+8],%g2
|
ldd [S2_PTR+8],%g2
|
||||||
std %o4,[res_ptr+0]
|
std %o4,[RES_PTR+0]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-2,size
|
addcc SIZE,-2,SIZE
|
||||||
add s1_ptr,8,s1_ptr
|
add S1_PTR,8,S1_PTR
|
||||||
add s2_ptr,8,s2_ptr
|
add S2_PTR,8,S2_PTR
|
||||||
add res_ptr,8,res_ptr
|
add RES_PTR,8,RES_PTR
|
||||||
bge Loope1
|
bge LOC(loope1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
Lend1: subxcc %g4,%g2,%o4
|
LOC(end1):
|
||||||
|
subxcc %g4,%g2,%o4
|
||||||
subxcc %g1,%g3,%o5
|
subxcc %g1,%g3,%o5
|
||||||
std %o4,[res_ptr+0]
|
std %o4,[RES_PTR+0]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
|
|
||||||
andcc size,1,%g0
|
andcc SIZE,1,%g0
|
||||||
be Lret1
|
be LOC(ret1)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add last limb */
|
/* Add last limb */
|
||||||
ld [s1_ptr+8],%g4
|
ld [S1_PTR+8],%g4
|
||||||
ld [s2_ptr+8],%g2
|
ld [S2_PTR+8],%g2
|
||||||
subxcc %g4,%g2,%o4
|
subxcc %g4,%g2,%o4
|
||||||
st %o4,[res_ptr+8]
|
st %o4,[RES_PTR+8]
|
||||||
|
|
||||||
Lret1: retl
|
LOC(ret1):
|
||||||
|
retl
|
||||||
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
||||||
|
|
||||||
L1: xor s1_ptr,res_ptr,%g1
|
LOC(1): xor S1_PTR,RES_PTR,%g1
|
||||||
andcc %g1,4,%g0
|
andcc %g1,4,%g0
|
||||||
bne L2
|
bne LOC(2)
|
||||||
nop
|
nop
|
||||||
! ** V1b **
|
! ** V1b **
|
||||||
andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
|
andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
|
||||||
be L_v1b ! if no, branch
|
be LOC(v1b) ! if no, branch
|
||||||
nop
|
nop
|
||||||
/* Add least significant limb separately to align res_ptr and s1_ptr */
|
/* Add least significant limb separately to align RES_PTR and S1_PTR */
|
||||||
ld [s2_ptr],%g4
|
ld [S2_PTR],%g4
|
||||||
add s2_ptr,4,s2_ptr
|
add S2_PTR,4,S2_PTR
|
||||||
ld [s1_ptr],%g2
|
ld [S1_PTR],%g2
|
||||||
add s1_ptr,4,s1_ptr
|
add S1_PTR,4,S1_PTR
|
||||||
add size,-1,size
|
add SIZE,-1,SIZE
|
||||||
subcc %g2,%g4,%o4
|
subcc %g2,%g4,%o4
|
||||||
st %o4,[res_ptr]
|
st %o4,[RES_PTR]
|
||||||
add res_ptr,4,res_ptr
|
add RES_PTR,4,RES_PTR
|
||||||
L_v1b: addx %g0,%g0,%o4 ! save cy in register
|
LOC(v1b):
|
||||||
cmp size,2 ! if size < 2 ...
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
bl Lend2 ! ... branch to tail code
|
cmp SIZE,2 ! if SIZE < 2 ...
|
||||||
|
bl LOC(end2) ! ... branch to tail code
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
|
|
||||||
ld [s2_ptr+0],%g4
|
ld [S2_PTR+0],%g4
|
||||||
addcc size,-10,size
|
addcc SIZE,-10,SIZE
|
||||||
ld [s2_ptr+4],%g1
|
ld [S2_PTR+4],%g1
|
||||||
ldd [s1_ptr+0],%g2
|
ldd [S1_PTR+0],%g2
|
||||||
blt Lfin1b
|
blt LOC(fin1b)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||||
Loop1b: subxcc %g2,%g4,%o4
|
LOC(loop1b):
|
||||||
ld [s2_ptr+8],%g4
|
|
||||||
subxcc %g3,%g1,%o5
|
|
||||||
ld [s2_ptr+12],%g1
|
|
||||||
ldd [s1_ptr+8],%g2
|
|
||||||
std %o4,[res_ptr+0]
|
|
||||||
subxcc %g2,%g4,%o4
|
subxcc %g2,%g4,%o4
|
||||||
ld [s2_ptr+16],%g4
|
ld [S2_PTR+8],%g4
|
||||||
subxcc %g3,%g1,%o5
|
subxcc %g3,%g1,%o5
|
||||||
ld [s2_ptr+20],%g1
|
ld [S2_PTR+12],%g1
|
||||||
ldd [s1_ptr+16],%g2
|
ldd [S1_PTR+8],%g2
|
||||||
std %o4,[res_ptr+8]
|
std %o4,[RES_PTR+0]
|
||||||
subxcc %g2,%g4,%o4
|
subxcc %g2,%g4,%o4
|
||||||
ld [s2_ptr+24],%g4
|
ld [S2_PTR+16],%g4
|
||||||
subxcc %g3,%g1,%o5
|
subxcc %g3,%g1,%o5
|
||||||
ld [s2_ptr+28],%g1
|
ld [S2_PTR+20],%g1
|
||||||
ldd [s1_ptr+24],%g2
|
ldd [S1_PTR+16],%g2
|
||||||
std %o4,[res_ptr+16]
|
std %o4,[RES_PTR+8]
|
||||||
subxcc %g2,%g4,%o4
|
subxcc %g2,%g4,%o4
|
||||||
ld [s2_ptr+32],%g4
|
ld [S2_PTR+24],%g4
|
||||||
subxcc %g3,%g1,%o5
|
subxcc %g3,%g1,%o5
|
||||||
ld [s2_ptr+36],%g1
|
ld [S2_PTR+28],%g1
|
||||||
ldd [s1_ptr+32],%g2
|
ldd [S1_PTR+24],%g2
|
||||||
std %o4,[res_ptr+24]
|
std %o4,[RES_PTR+16]
|
||||||
|
subxcc %g2,%g4,%o4
|
||||||
|
ld [S2_PTR+32],%g4
|
||||||
|
subxcc %g3,%g1,%o5
|
||||||
|
ld [S2_PTR+36],%g1
|
||||||
|
ldd [S1_PTR+32],%g2
|
||||||
|
std %o4,[RES_PTR+24]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-8,size
|
addcc SIZE,-8,SIZE
|
||||||
add s1_ptr,32,s1_ptr
|
add S1_PTR,32,S1_PTR
|
||||||
add s2_ptr,32,s2_ptr
|
add S2_PTR,32,S2_PTR
|
||||||
add res_ptr,32,res_ptr
|
add RES_PTR,32,RES_PTR
|
||||||
bge Loop1b
|
bge LOC(loop1b)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
|
|
||||||
Lfin1b: addcc size,8-2,size
|
LOC(fin1b):
|
||||||
blt Lend1b
|
addcc SIZE,8-2,SIZE
|
||||||
|
blt LOC(end1b)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add blocks of 2 limbs until less than 2 limbs remain */
|
/* Add blocks of 2 limbs until less than 2 limbs remain */
|
||||||
Loope1b:subxcc %g2,%g4,%o4
|
LOC(loope1b):
|
||||||
ld [s2_ptr+8],%g4
|
subxcc %g2,%g4,%o4
|
||||||
|
ld [S2_PTR+8],%g4
|
||||||
subxcc %g3,%g1,%o5
|
subxcc %g3,%g1,%o5
|
||||||
ld [s2_ptr+12],%g1
|
ld [S2_PTR+12],%g1
|
||||||
ldd [s1_ptr+8],%g2
|
ldd [S1_PTR+8],%g2
|
||||||
std %o4,[res_ptr+0]
|
std %o4,[RES_PTR+0]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-2,size
|
addcc SIZE,-2,SIZE
|
||||||
add s1_ptr,8,s1_ptr
|
add S1_PTR,8,S1_PTR
|
||||||
add s2_ptr,8,s2_ptr
|
add S2_PTR,8,S2_PTR
|
||||||
add res_ptr,8,res_ptr
|
add RES_PTR,8,RES_PTR
|
||||||
bge Loope1b
|
bge LOC(loope1b)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
Lend1b: subxcc %g2,%g4,%o4
|
LOC(end1b):
|
||||||
|
subxcc %g2,%g4,%o4
|
||||||
subxcc %g3,%g1,%o5
|
subxcc %g3,%g1,%o5
|
||||||
std %o4,[res_ptr+0]
|
std %o4,[RES_PTR+0]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
|
|
||||||
andcc size,1,%g0
|
andcc SIZE,1,%g0
|
||||||
be Lret1b
|
be LOC(ret1b)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add last limb */
|
/* Add last limb */
|
||||||
ld [s2_ptr+8],%g4
|
ld [S2_PTR+8],%g4
|
||||||
ld [s1_ptr+8],%g2
|
ld [S1_PTR+8],%g2
|
||||||
subxcc %g2,%g4,%o4
|
subxcc %g2,%g4,%o4
|
||||||
st %o4,[res_ptr+8]
|
st %o4,[RES_PTR+8]
|
||||||
|
|
||||||
Lret1b: retl
|
LOC(ret1b):
|
||||||
|
retl
|
||||||
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
||||||
|
|
||||||
! ** V2 **
|
! ** V2 **
|
||||||
/* If we come here, the alignment of s1_ptr and res_ptr as well as the
|
/* If we come here, the alignment of S1_PTR and RES_PTR as well as the
|
||||||
alignment of s2_ptr and res_ptr differ. Since there are only two ways
|
alignment of S2_PTR and RES_PTR differ. Since there are only two ways
|
||||||
things can be aligned (that we care about) we now know that the alignment
|
things can be aligned (that we care about) we now know that the alignment
|
||||||
of s1_ptr and s2_ptr are the same. */
|
of S1_PTR and S2_PTR are the same. */
|
||||||
|
|
||||||
L2: cmp size,1
|
LOC(2): cmp SIZE,1
|
||||||
be Ljone
|
be LOC(jone)
|
||||||
nop
|
nop
|
||||||
andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
|
andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
|
||||||
be L_v2 ! if no, branch
|
be LOC(v2) ! if no, branch
|
||||||
nop
|
nop
|
||||||
/* Add least significant limb separately to align s1_ptr and s2_ptr */
|
/* Add least significant limb separately to align S1_PTR and S2_PTR */
|
||||||
ld [s1_ptr],%g4
|
ld [S1_PTR],%g4
|
||||||
add s1_ptr,4,s1_ptr
|
add S1_PTR,4,S1_PTR
|
||||||
ld [s2_ptr],%g2
|
ld [S2_PTR],%g2
|
||||||
add s2_ptr,4,s2_ptr
|
add S2_PTR,4,S2_PTR
|
||||||
add size,-1,size
|
add SIZE,-1,SIZE
|
||||||
subcc %g4,%g2,%o4
|
subcc %g4,%g2,%o4
|
||||||
st %o4,[res_ptr]
|
st %o4,[RES_PTR]
|
||||||
add res_ptr,4,res_ptr
|
add RES_PTR,4,RES_PTR
|
||||||
|
|
||||||
L_v2: addx %g0,%g0,%o4 ! save cy in register
|
LOC(v2):
|
||||||
addcc size,-8,size
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
blt Lfin2
|
addcc SIZE,-8,SIZE
|
||||||
|
blt LOC(fin2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
/* Add blocks of 8 limbs until less than 8 limbs remain */
|
||||||
Loop2: ldd [s1_ptr+0],%g2
|
LOC(loop2):
|
||||||
ldd [s2_ptr+0],%o4
|
ldd [S1_PTR+0],%g2
|
||||||
|
ldd [S2_PTR+0],%o4
|
||||||
subxcc %g2,%o4,%g2
|
subxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+0]
|
st %g2,[RES_PTR+0]
|
||||||
subxcc %g3,%o5,%g3
|
subxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+4]
|
st %g3,[RES_PTR+4]
|
||||||
ldd [s1_ptr+8],%g2
|
ldd [S1_PTR+8],%g2
|
||||||
ldd [s2_ptr+8],%o4
|
ldd [S2_PTR+8],%o4
|
||||||
subxcc %g2,%o4,%g2
|
subxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+8]
|
st %g2,[RES_PTR+8]
|
||||||
subxcc %g3,%o5,%g3
|
subxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+12]
|
st %g3,[RES_PTR+12]
|
||||||
ldd [s1_ptr+16],%g2
|
ldd [S1_PTR+16],%g2
|
||||||
ldd [s2_ptr+16],%o4
|
ldd [S2_PTR+16],%o4
|
||||||
subxcc %g2,%o4,%g2
|
subxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+16]
|
st %g2,[RES_PTR+16]
|
||||||
subxcc %g3,%o5,%g3
|
subxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+20]
|
st %g3,[RES_PTR+20]
|
||||||
ldd [s1_ptr+24],%g2
|
ldd [S1_PTR+24],%g2
|
||||||
ldd [s2_ptr+24],%o4
|
ldd [S2_PTR+24],%o4
|
||||||
subxcc %g2,%o4,%g2
|
subxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+24]
|
st %g2,[RES_PTR+24]
|
||||||
subxcc %g3,%o5,%g3
|
subxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+28]
|
st %g3,[RES_PTR+28]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-8,size
|
addcc SIZE,-8,SIZE
|
||||||
add s1_ptr,32,s1_ptr
|
add S1_PTR,32,S1_PTR
|
||||||
add s2_ptr,32,s2_ptr
|
add S2_PTR,32,S2_PTR
|
||||||
add res_ptr,32,res_ptr
|
add RES_PTR,32,RES_PTR
|
||||||
bge Loop2
|
bge LOC(loop2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
|
|
||||||
Lfin2: addcc size,8-2,size
|
LOC(fin2):
|
||||||
blt Lend2
|
addcc SIZE,8-2,SIZE
|
||||||
|
blt LOC(end2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
Loope2: ldd [s1_ptr+0],%g2
|
LOC(loope2):
|
||||||
ldd [s2_ptr+0],%o4
|
ldd [S1_PTR+0],%g2
|
||||||
|
ldd [S2_PTR+0],%o4
|
||||||
subxcc %g2,%o4,%g2
|
subxcc %g2,%o4,%g2
|
||||||
st %g2,[res_ptr+0]
|
st %g2,[RES_PTR+0]
|
||||||
subxcc %g3,%o5,%g3
|
subxcc %g3,%o5,%g3
|
||||||
st %g3,[res_ptr+4]
|
st %g3,[RES_PTR+4]
|
||||||
addx %g0,%g0,%o4 ! save cy in register
|
addx %g0,%g0,%o4 ! save cy in register
|
||||||
addcc size,-2,size
|
addcc SIZE,-2,SIZE
|
||||||
add s1_ptr,8,s1_ptr
|
add S1_PTR,8,S1_PTR
|
||||||
add s2_ptr,8,s2_ptr
|
add S2_PTR,8,S2_PTR
|
||||||
add res_ptr,8,res_ptr
|
add RES_PTR,8,RES_PTR
|
||||||
bge Loope2
|
bge LOC(loope2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
Lend2: andcc size,1,%g0
|
LOC(end2):
|
||||||
be Lret2
|
andcc SIZE,1,%g0
|
||||||
|
be LOC(ret2)
|
||||||
subcc %g0,%o4,%g0 ! restore cy
|
subcc %g0,%o4,%g0 ! restore cy
|
||||||
/* Add last limb */
|
/* Add last limb */
|
||||||
Ljone: ld [s1_ptr],%g4
|
LOC(jone):
|
||||||
ld [s2_ptr],%g2
|
ld [S1_PTR],%g4
|
||||||
|
ld [S2_PTR],%g2
|
||||||
subxcc %g4,%g2,%o4
|
subxcc %g4,%g2,%o4
|
||||||
st %o4,[res_ptr]
|
st %o4,[RES_PTR]
|
||||||
|
|
||||||
Lret2: retl
|
LOC(ret2):
|
||||||
|
retl
|
||||||
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
addx %g0,%g0,%o0 ! return carry-out from most sign. limb
|
||||||
|
|
||||||
|
END(__mpn_sub_n)
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
|
! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
|
||||||
! the result from a second limb vector.
|
! the result from a second limb vector.
|
||||||
|
!
|
||||||
! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
|
! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
|
||||||
|
!
|
||||||
! This file is part of the GNU MP Library.
|
! This file is part of the GNU MP Library.
|
||||||
|
!
|
||||||
! The GNU MP Library is free software; you can redistribute it and/or modify
|
! The GNU MP Library is free software; you can redistribute it and/or modify
|
||||||
! it under the terms of the GNU Library General Public License as published by
|
! it under the terms of the GNU Library General Public License as published by
|
||||||
! the Free Software Foundation; either version 2 of the License, or (at your
|
! the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
! option) any later version.
|
! option) any later version.
|
||||||
|
!
|
||||||
! The GNU MP Library is distributed in the hope that it will be useful, but
|
! The GNU MP Library is distributed in the hope that it will be useful, but
|
||||||
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
! License for more details.
|
! License for more details.
|
||||||
|
!
|
||||||
! You should have received a copy of the GNU Library General Public License
|
! You should have received a copy of the GNU Library General Public License
|
||||||
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||||
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
@ -22,17 +22,14 @@
|
|||||||
|
|
||||||
|
|
||||||
! INPUT PARAMETERS
|
! INPUT PARAMETERS
|
||||||
! res_ptr o0
|
! RES_PTR o0
|
||||||
! s1_ptr o1
|
! S1_PTR o1
|
||||||
! size o2
|
! SIZE o2
|
||||||
! s2_limb o3
|
! S2_LIMB o3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
|
|
||||||
.text
|
ENTRY(__mpn_submul_1)
|
||||||
.align 4
|
|
||||||
.global C_SYMBOL_NAME(__mpn_submul_1)
|
|
||||||
C_SYMBOL_NAME(__mpn_submul_1):
|
|
||||||
! Make S1_PTR and RES_PTR point at the end of their blocks
|
! Make S1_PTR and RES_PTR point at the end of their blocks
|
||||||
! and put (- 4 x SIZE) in index/loop counter.
|
! and put (- 4 x SIZE) in index/loop counter.
|
||||||
sll %o2,2,%o2
|
sll %o2,2,%o2
|
||||||
@ -41,19 +38,19 @@ C_SYMBOL_NAME(__mpn_submul_1):
|
|||||||
sub %g0,%o2,%o2
|
sub %g0,%o2,%o2
|
||||||
|
|
||||||
cmp %o3,0xfff
|
cmp %o3,0xfff
|
||||||
bgu Large
|
bgu LOC(large)
|
||||||
nop
|
nop
|
||||||
|
|
||||||
ld [%o1+%o2],%o5
|
ld [%o1+%o2],%o5
|
||||||
mov 0,%o0
|
mov 0,%o0
|
||||||
b L0
|
b LOC(0)
|
||||||
add %o4,-4,%o4
|
add %o4,-4,%o4
|
||||||
Loop0:
|
LOC(loop0):
|
||||||
subcc %o5,%g1,%g1
|
subcc %o5,%g1,%g1
|
||||||
ld [%o1+%o2],%o5
|
ld [%o1+%o2],%o5
|
||||||
addx %o0,%g0,%o0
|
addx %o0,%g0,%o0
|
||||||
st %g1,[%o4+%o2]
|
st %g1,[%o4+%o2]
|
||||||
L0: wr %g0,%o3,%y
|
LOC(0): wr %g0,%o3,%y
|
||||||
sra %o5,31,%g2
|
sra %o5,31,%g2
|
||||||
and %o3,%g2,%g2
|
and %o3,%g2,%g2
|
||||||
andcc %g1,0,%g1
|
andcc %g1,0,%g1
|
||||||
@ -79,7 +76,7 @@ L0: wr %g0,%o3,%y
|
|||||||
addcc %g1,%o0,%g1
|
addcc %g1,%o0,%g1
|
||||||
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
|
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
|
||||||
addcc %o2,4,%o2 ! loop counter
|
addcc %o2,4,%o2 ! loop counter
|
||||||
bne Loop0
|
bne LOC(loop0)
|
||||||
ld [%o4+%o2],%o5
|
ld [%o4+%o2],%o5
|
||||||
|
|
||||||
subcc %o5,%g1,%g1
|
subcc %o5,%g1,%g1
|
||||||
@ -88,17 +85,18 @@ L0: wr %g0,%o3,%y
|
|||||||
st %g1,[%o4+%o2]
|
st %g1,[%o4+%o2]
|
||||||
|
|
||||||
|
|
||||||
Large: ld [%o1+%o2],%o5
|
LOC(large):
|
||||||
|
ld [%o1+%o2],%o5
|
||||||
mov 0,%o0
|
mov 0,%o0
|
||||||
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
|
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
|
||||||
b L1
|
b LOC(1)
|
||||||
add %o4,-4,%o4
|
add %o4,-4,%o4
|
||||||
Loop:
|
LOC(loop):
|
||||||
subcc %o5,%g3,%g3
|
subcc %o5,%g3,%g3
|
||||||
ld [%o1+%o2],%o5
|
ld [%o1+%o2],%o5
|
||||||
addx %o0,%g0,%o0
|
addx %o0,%g0,%o0
|
||||||
st %g3,[%o4+%o2]
|
st %g3,[%o4+%o2]
|
||||||
L1: wr %g0,%o5,%y
|
LOC(1): wr %g0,%o5,%y
|
||||||
and %o5,%g4,%g2
|
and %o5,%g4,%g2
|
||||||
andcc %g0,%g0,%g1
|
andcc %g0,%g0,%g1
|
||||||
mulscc %g1,%o3,%g1
|
mulscc %g1,%o3,%g1
|
||||||
@ -138,10 +136,12 @@ L1: wr %g0,%o5,%y
|
|||||||
addcc %g3,%o0,%g3
|
addcc %g3,%o0,%g3
|
||||||
addx %g2,%g1,%o0
|
addx %g2,%g1,%o0
|
||||||
addcc %o2,4,%o2
|
addcc %o2,4,%o2
|
||||||
bne Loop
|
bne LOC(loop)
|
||||||
ld [%o4+%o2],%o5
|
ld [%o4+%o2],%o5
|
||||||
|
|
||||||
subcc %o5,%g3,%g3
|
subcc %o5,%g3,%g3
|
||||||
addx %o0,%g0,%o0
|
addx %o0,%g0,%o0
|
||||||
retl
|
retl
|
||||||
st %g3,[%o4+%o2]
|
st %g3,[%o4+%o2]
|
||||||
|
|
||||||
|
END(__mpn_submul_1)
|
||||||
|
@ -37,16 +37,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
#ifdef __linux__
|
|
||||||
#include <asm/traps.h>
|
|
||||||
#else
|
|
||||||
#ifdef __svr4__
|
|
||||||
#include <sys/trap.h>
|
#include <sys/trap.h>
|
||||||
#else
|
|
||||||
#include <machine/trap.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ENTRY(.udiv)
|
ENTRY(.udiv)
|
||||||
|
|
||||||
@ -63,11 +55,11 @@ ENTRY(.udiv)
|
|||||||
|
|
||||||
1:
|
1:
|
||||||
cmp %o3, %o5 ! if %o1 exceeds %o0, done
|
cmp %o3, %o5 ! if %o1 exceeds %o0, done
|
||||||
blu Lgot_result ! (and algorithm fails otherwise)
|
blu LOC(got_result) ! (and algorithm fails otherwise)
|
||||||
clr %o2
|
clr %o2
|
||||||
sethi %hi(1 << (32 - 4 - 1)), %g1
|
sethi %hi(1 << (32 - 4 - 1)), %g1
|
||||||
cmp %o3, %g1
|
cmp %o3, %g1
|
||||||
blu Lnot_really_big
|
blu LOC(not_really_big)
|
||||||
clr %o4
|
clr %o4
|
||||||
|
|
||||||
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
||||||
@ -78,15 +70,15 @@ ENTRY(.udiv)
|
|||||||
1:
|
1:
|
||||||
cmp %o5, %g1
|
cmp %o5, %g1
|
||||||
bgeu 3f
|
bgeu 3f
|
||||||
mov 1, %g7
|
mov 1, %g2
|
||||||
sll %o5, 4, %o5
|
sll %o5, 4, %o5
|
||||||
b 1b
|
b 1b
|
||||||
add %o4, 1, %o4
|
add %o4, 1, %o4
|
||||||
|
|
||||||
! Now compute %g7.
|
! Now compute %g2.
|
||||||
2: addcc %o5, %o5, %o5
|
2: addcc %o5, %o5, %o5
|
||||||
bcc Lnot_too_big
|
bcc LOC(not_too_big)
|
||||||
add %g7, 1, %g7
|
add %g2, 1, %g2
|
||||||
|
|
||||||
! We get here if the %o1 overflowed while shifting.
|
! We get here if the %o1 overflowed while shifting.
|
||||||
! This means that %o3 has the high-order bit set.
|
! This means that %o3 has the high-order bit set.
|
||||||
@ -94,20 +86,20 @@ ENTRY(.udiv)
|
|||||||
sll %g1, 4, %g1 ! high order bit
|
sll %g1, 4, %g1 ! high order bit
|
||||||
srl %o5, 1, %o5 ! rest of %o5
|
srl %o5, 1, %o5 ! rest of %o5
|
||||||
add %o5, %g1, %o5
|
add %o5, %g1, %o5
|
||||||
b Ldo_single_div
|
b LOC(do_single_div)
|
||||||
sub %g7, 1, %g7
|
sub %g2, 1, %g2
|
||||||
|
|
||||||
Lnot_too_big:
|
LOC(not_too_big):
|
||||||
3: cmp %o5, %o3
|
3: cmp %o5, %o3
|
||||||
blu 2b
|
blu 2b
|
||||||
nop
|
nop
|
||||||
be Ldo_single_div
|
be LOC(do_single_div)
|
||||||
nop
|
nop
|
||||||
/* NB: these are commented out in the V8-Sparc manual as well */
|
/* NB: these are commented out in the V8-Sparc manual as well */
|
||||||
/* (I do not understand this) */
|
/* (I do not understand this) */
|
||||||
! %o5 > %o3: went too far: back up 1 step
|
! %o5 > %o3: went too far: back up 1 step
|
||||||
! srl %o5, 1, %o5
|
! srl %o5, 1, %o5
|
||||||
! dec %g7
|
! dec %g2
|
||||||
! do single-bit divide steps
|
! do single-bit divide steps
|
||||||
!
|
!
|
||||||
! We have to be careful here. We know that %o3 >= %o5, so we can do the
|
! We have to be careful here. We know that %o3 >= %o5, so we can do the
|
||||||
@ -116,15 +108,15 @@ ENTRY(.udiv)
|
|||||||
! order bit set in the first step, just falling into the regular
|
! order bit set in the first step, just falling into the regular
|
||||||
! division loop will mess up the first time around.
|
! division loop will mess up the first time around.
|
||||||
! So we unroll slightly...
|
! So we unroll slightly...
|
||||||
Ldo_single_div:
|
LOC(do_single_div):
|
||||||
subcc %g7, 1, %g7
|
subcc %g2, 1, %g2
|
||||||
bl Lend_regular_divide
|
bl LOC(end_regular_divide)
|
||||||
nop
|
nop
|
||||||
sub %o3, %o5, %o3
|
sub %o3, %o5, %o3
|
||||||
mov 1, %o2
|
mov 1, %o2
|
||||||
b Lend_single_divloop
|
b LOC(end_single_divloop)
|
||||||
nop
|
nop
|
||||||
Lsingle_divloop:
|
LOC(single_divloop):
|
||||||
sll %o2, 1, %o2
|
sll %o2, 1, %o2
|
||||||
bl 1f
|
bl 1f
|
||||||
srl %o5, 1, %o5
|
srl %o5, 1, %o5
|
||||||
@ -136,217 +128,219 @@ ENTRY(.udiv)
|
|||||||
add %o3, %o5, %o3
|
add %o3, %o5, %o3
|
||||||
sub %o2, 1, %o2
|
sub %o2, 1, %o2
|
||||||
2:
|
2:
|
||||||
Lend_single_divloop:
|
LOC(end_single_divloop):
|
||||||
subcc %g7, 1, %g7
|
subcc %g2, 1, %g2
|
||||||
bge Lsingle_divloop
|
bge LOC(single_divloop)
|
||||||
tst %o3
|
tst %o3
|
||||||
b,a Lend_regular_divide
|
b,a LOC(end_regular_divide)
|
||||||
|
|
||||||
Lnot_really_big:
|
LOC(not_really_big):
|
||||||
1:
|
1:
|
||||||
sll %o5, 4, %o5
|
sll %o5, 4, %o5
|
||||||
cmp %o5, %o3
|
cmp %o5, %o3
|
||||||
bleu 1b
|
bleu 1b
|
||||||
addcc %o4, 1, %o4
|
addcc %o4, 1, %o4
|
||||||
be Lgot_result
|
be LOC(got_result)
|
||||||
sub %o4, 1, %o4
|
sub %o4, 1, %o4
|
||||||
|
|
||||||
tst %o3 ! set up for initial iteration
|
tst %o3 ! set up for initial iteration
|
||||||
Ldivloop:
|
LOC(divloop):
|
||||||
sll %o2, 4, %o2
|
sll %o2, 4, %o2
|
||||||
! depth 1, accumulated bits 0
|
! depth 1, accumulated bits 0
|
||||||
bl L.1.16
|
bl LOC(1.16)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 2, accumulated bits 1
|
! depth 2, accumulated bits 1
|
||||||
bl L.2.17
|
bl LOC(2.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits 3
|
! depth 3, accumulated bits 3
|
||||||
bl L.3.19
|
bl LOC(3.19)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 7
|
! depth 4, accumulated bits 7
|
||||||
bl L.4.23
|
bl LOC(4.23)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (7*2+1), %o2
|
add %o2, (7*2+1), %o2
|
||||||
|
|
||||||
L.4.23:
|
LOC(4.23):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (7*2-1), %o2
|
add %o2, (7*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.19:
|
LOC(3.19):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 5
|
! depth 4, accumulated bits 5
|
||||||
bl L.4.21
|
bl LOC(4.21)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (5*2+1), %o2
|
add %o2, (5*2+1), %o2
|
||||||
|
|
||||||
L.4.21:
|
LOC(4.21):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (5*2-1), %o2
|
add %o2, (5*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.2.17:
|
LOC(2.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits 1
|
! depth 3, accumulated bits 1
|
||||||
bl L.3.17
|
bl LOC(3.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 3
|
! depth 4, accumulated bits 3
|
||||||
bl L.4.19
|
bl LOC(4.19)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (3*2+1), %o2
|
add %o2, (3*2+1), %o2
|
||||||
|
|
||||||
L.4.19:
|
LOC(4.19):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (3*2-1), %o2
|
add %o2, (3*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.17:
|
LOC(3.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 1
|
! depth 4, accumulated bits 1
|
||||||
bl L.4.17
|
bl LOC(4.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (1*2+1), %o2
|
add %o2, (1*2+1), %o2
|
||||||
|
|
||||||
L.4.17:
|
LOC(4.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (1*2-1), %o2
|
add %o2, (1*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.1.16:
|
LOC(1.16):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 2, accumulated bits -1
|
! depth 2, accumulated bits -1
|
||||||
bl L.2.15
|
bl LOC(2.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits -1
|
! depth 3, accumulated bits -1
|
||||||
bl L.3.15
|
bl LOC(3.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -1
|
! depth 4, accumulated bits -1
|
||||||
bl L.4.15
|
bl LOC(4.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-1*2+1), %o2
|
add %o2, (-1*2+1), %o2
|
||||||
|
|
||||||
L.4.15:
|
LOC(4.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-1*2-1), %o2
|
add %o2, (-1*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.15:
|
LOC(3.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -3
|
! depth 4, accumulated bits -3
|
||||||
bl L.4.13
|
bl LOC(4.13)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-3*2+1), %o2
|
add %o2, (-3*2+1), %o2
|
||||||
|
|
||||||
L.4.13:
|
LOC(4.13):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-3*2-1), %o2
|
add %o2, (-3*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.2.15:
|
LOC(2.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits -3
|
! depth 3, accumulated bits -3
|
||||||
bl L.3.13
|
bl LOC(3.13)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -5
|
! depth 4, accumulated bits -5
|
||||||
bl L.4.11
|
bl LOC(4.11)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-5*2+1), %o2
|
add %o2, (-5*2+1), %o2
|
||||||
|
|
||||||
L.4.11:
|
LOC(4.11):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-5*2-1), %o2
|
add %o2, (-5*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.13:
|
LOC(3.13):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -7
|
! depth 4, accumulated bits -7
|
||||||
bl L.4.9
|
bl LOC(4.9)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-7*2+1), %o2
|
add %o2, (-7*2+1), %o2
|
||||||
|
|
||||||
L.4.9:
|
LOC(4.9):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-7*2-1), %o2
|
add %o2, (-7*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
9:
|
9:
|
||||||
Lend_regular_divide:
|
LOC(end_regular_divide):
|
||||||
subcc %o4, 1, %o4
|
subcc %o4, 1, %o4
|
||||||
bge Ldivloop
|
bge LOC(divloop)
|
||||||
tst %o3
|
tst %o3
|
||||||
bl,a Lgot_result
|
bl,a LOC(got_result)
|
||||||
! non-restoring fixup here (one instruction only!)
|
! non-restoring fixup here (one instruction only!)
|
||||||
sub %o2, 1, %o2
|
sub %o2, 1, %o2
|
||||||
|
|
||||||
|
|
||||||
Lgot_result:
|
LOC(got_result):
|
||||||
|
|
||||||
retl
|
retl
|
||||||
mov %o2, %o0
|
mov %o2, %o0
|
||||||
|
|
||||||
|
END(.udiv)
|
||||||
|
@ -1,50 +1,52 @@
|
|||||||
! SPARC __udiv_qrnnd division support, used from longlong.h.
|
! SPARC __udiv_qrnnd division support, used from longlong.h.
|
||||||
|
!
|
||||||
! Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
|
! Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
|
||||||
|
!
|
||||||
! This file is part of the GNU MP Library.
|
! This file is part of the GNU MP Library.
|
||||||
|
!
|
||||||
! The GNU MP Library is free software; you can redistribute it and/or modify
|
! The GNU MP Library is free software; you can redistribute it and/or modify
|
||||||
! it under the terms of the GNU Library General Public License as published by
|
! it under the terms of the GNU Library General Public License as published by
|
||||||
! the Free Software Foundation; either version 2 of the License, or (at your
|
! the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
! option) any later version.
|
! option) any later version.
|
||||||
|
!
|
||||||
! The GNU MP Library is distributed in the hope that it will be useful, but
|
! The GNU MP Library is distributed in the hope that it will be useful, but
|
||||||
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
! License for more details.
|
! License for more details.
|
||||||
|
!
|
||||||
! You should have received a copy of the GNU Library General Public License
|
! You should have received a copy of the GNU Library General Public License
|
||||||
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||||
! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
!
|
||||||
! Added PIC support - May/96, Miguel de Icaza
|
! Added PIC support - May/96, Miguel de Icaza
|
||||||
|
!
|
||||||
! INPUT PARAMETERS
|
! INPUT PARAMETERS
|
||||||
! rem_ptr i0
|
! rem_ptr i0
|
||||||
! n1 i1
|
! n1 i1
|
||||||
! n0 i2
|
! n0 i2
|
||||||
! d i3
|
! d i3
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
#undef ret /* Kludge for glibc */
|
#undef ret /* Kludge for glibc */
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
.text
|
.text
|
||||||
|
#else
|
||||||
|
.section .rodata,#alloc
|
||||||
|
#endif
|
||||||
.align 8
|
.align 8
|
||||||
|
|
||||||
.type two_to_32,@object
|
.type two_to_32,@object
|
||||||
|
.size two_to_32,8
|
||||||
two_to_32:
|
two_to_32:
|
||||||
.double 0r4294967296
|
.double 0r4294967296
|
||||||
.size two_to_32,8
|
|
||||||
|
|
||||||
.type two_to_31,@object
|
.type two_to_31,@object
|
||||||
|
.size two_to_31,8
|
||||||
two_to_31:
|
two_to_31:
|
||||||
.double 0r2147483648
|
.double 0r2147483648
|
||||||
.size two_to_31,8
|
|
||||||
|
|
||||||
.align 4
|
.text
|
||||||
.global __udiv_qrnnd
|
|
||||||
.type __udiv_qrnnd,@function
|
|
||||||
ENTRY(__udiv_qrnnd)
|
ENTRY(__udiv_qrnnd)
|
||||||
!#PROLOGUE# 0
|
!#PROLOGUE# 0
|
||||||
save %sp,-104,%sp
|
save %sp,-104,%sp
|
||||||
@ -52,57 +54,58 @@ ENTRY(__udiv_qrnnd)
|
|||||||
st %i1,[%fp-8]
|
st %i1,[%fp-8]
|
||||||
ld [%fp-8],%f10
|
ld [%fp-8],%f10
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
.Lbase: call 1f
|
LOC(base):
|
||||||
|
call 1f
|
||||||
fitod %f10,%f4
|
fitod %f10,%f4
|
||||||
1: ldd [%o7-(.Lbase-two_to_32)],%f8
|
1: ldd [%o7-(LOC(base)-two_to_32)],%f8
|
||||||
#else
|
#else
|
||||||
sethi %hi(two_to_32),%o7
|
sethi %hi(two_to_32),%o7
|
||||||
fitod %f10,%f4
|
fitod %f10,%f4
|
||||||
ldd [%o7+%lo(two_to_32)],%f8
|
ldd [%o7+%lo(two_to_32)],%f8
|
||||||
#endif
|
#endif
|
||||||
cmp %i1,0
|
cmp %i1,0
|
||||||
bge L248
|
bge LOC(248)
|
||||||
mov %i0,%i5
|
mov %i0,%i5
|
||||||
faddd %f4,%f8,%f4
|
faddd %f4,%f8,%f4
|
||||||
.L248:
|
LOC(248):
|
||||||
st %i2,[%fp-8]
|
st %i2,[%fp-8]
|
||||||
ld [%fp-8],%f10
|
ld [%fp-8],%f10
|
||||||
fmuld %f4,%f8,%f6
|
fmuld %f4,%f8,%f6
|
||||||
cmp %i2,0
|
cmp %i2,0
|
||||||
bge L249
|
bge LOC(249)
|
||||||
fitod %f10,%f2
|
fitod %f10,%f2
|
||||||
faddd %f2,%f8,%f2
|
faddd %f2,%f8,%f2
|
||||||
.L249:
|
LOC(249):
|
||||||
st %i3,[%fp-8]
|
st %i3,[%fp-8]
|
||||||
faddd %f6,%f2,%f2
|
faddd %f6,%f2,%f2
|
||||||
ld [%fp-8],%f10
|
ld [%fp-8],%f10
|
||||||
cmp %i3,0
|
cmp %i3,0
|
||||||
bge L250
|
bge LOC(250)
|
||||||
fitod %f10,%f4
|
fitod %f10,%f4
|
||||||
faddd %f4,%f8,%f4
|
faddd %f4,%f8,%f4
|
||||||
.L250:
|
LOC(250):
|
||||||
fdivd %f2,%f4,%f2
|
fdivd %f2,%f4,%f2
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
ldd [%o7-(.Lbase-two_to_31)],%f4
|
ldd [%o7-(LOC(base)-two_to_31)],%f4
|
||||||
#else
|
#else
|
||||||
sethi %hi(two_to_31),%o7
|
sethi %hi(two_to_31),%o7
|
||||||
ldd [%o7+%lo(two_to_31)],%f4
|
ldd [%o7+%lo(two_to_31)],%f4
|
||||||
#endif
|
#endif
|
||||||
fcmped %f2,%f4
|
fcmped %f2,%f4
|
||||||
nop
|
nop
|
||||||
fbge,a L251
|
fbge,a LOC(251)
|
||||||
fsubd %f2,%f4,%f2
|
fsubd %f2,%f4,%f2
|
||||||
fdtoi %f2,%f2
|
fdtoi %f2,%f2
|
||||||
st %f2,[%fp-8]
|
st %f2,[%fp-8]
|
||||||
b L252
|
b LOC(252)
|
||||||
ld [%fp-8],%i4
|
ld [%fp-8],%i4
|
||||||
.L251:
|
LOC(251):
|
||||||
fdtoi %f2,%f2
|
fdtoi %f2,%f2
|
||||||
st %f2,[%fp-8]
|
st %f2,[%fp-8]
|
||||||
ld [%fp-8],%i4
|
ld [%fp-8],%i4
|
||||||
sethi %hi(-2147483648),%g2
|
sethi %hi(-2147483648),%g2
|
||||||
xor %i4,%g2,%i4
|
xor %i4,%g2,%i4
|
||||||
.L252:
|
LOC(252):
|
||||||
wr %g0,%i4,%y
|
wr %g0,%i4,%y
|
||||||
sra %i3,31,%g2
|
sra %i3,31,%g2
|
||||||
and %i4,%g2,%g2
|
and %i4,%g2,%g2
|
||||||
@ -144,7 +147,7 @@ ENTRY(__udiv_qrnnd)
|
|||||||
rd %y,%g3
|
rd %y,%g3
|
||||||
subcc %i2,%g3,%o7
|
subcc %i2,%g3,%o7
|
||||||
subxcc %i1,%i0,%g0
|
subxcc %i1,%i0,%g0
|
||||||
be L253
|
be LOC(253)
|
||||||
cmp %o7,%i3
|
cmp %o7,%i3
|
||||||
|
|
||||||
add %i4,-1,%i0
|
add %i4,-1,%i0
|
||||||
@ -152,14 +155,14 @@ ENTRY(__udiv_qrnnd)
|
|||||||
st %o7,[%i5]
|
st %o7,[%i5]
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
.L253:
|
LOC(253):
|
||||||
blu L246
|
blu LOC(246)
|
||||||
mov %i4,%i0
|
mov %i4,%i0
|
||||||
add %i4,1,%i0
|
add %i4,1,%i0
|
||||||
sub %o7,%i3,%o7
|
sub %o7,%i3,%o7
|
||||||
.L246:
|
LOC(246):
|
||||||
st %o7,[%i5]
|
st %o7,[%i5]
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
|
|
||||||
.size __udiv_qrnnd, .-__udiv_qrnnd
|
END(__udiv_qrnnd)
|
||||||
|
@ -14,13 +14,14 @@
|
|||||||
* bnz overflow (or tnz)
|
* bnz overflow (or tnz)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "DEFS.h"
|
#include <sysdep.h>
|
||||||
FUNC(.umul)
|
|
||||||
|
ENTRY(.umul)
|
||||||
or %o0, %o1, %o4
|
or %o0, %o1, %o4
|
||||||
mov %o0, %y ! multiplier -> Y
|
mov %o0, %y ! multiplier -> Y
|
||||||
andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
|
andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
|
||||||
be Lmul_shortway ! if zero, can do it the short way
|
be LOC(mul_shortway) ! if zero, can do it the short way
|
||||||
andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
|
andcc %g0, %g0, %o4 ! zero the partial product; clear N & V
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Long multiply. 32 steps, followed by a final shift step.
|
* Long multiply. 32 steps, followed by a final shift step.
|
||||||
@ -59,7 +60,6 @@ FUNC(.umul)
|
|||||||
mulscc %o4, %o1, %o4 ! 32
|
mulscc %o4, %o1, %o4 ! 32
|
||||||
mulscc %o4, %g0, %o4 ! final shift
|
mulscc %o4, %g0, %o4 ! final shift
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Normally, with the shift-and-add approach, if both numbers are
|
* Normally, with the shift-and-add approach, if both numbers are
|
||||||
* positive you get the correct result. With 32-bit two's-complement
|
* positive you get the correct result. With 32-bit two's-complement
|
||||||
@ -97,20 +97,20 @@ FUNC(.umul)
|
|||||||
#if 0
|
#if 0
|
||||||
tst %o1
|
tst %o1
|
||||||
bl,a 1f ! if %o1 < 0 (high order bit = 1),
|
bl,a 1f ! if %o1 < 0 (high order bit = 1),
|
||||||
add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half)
|
add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half)
|
||||||
1: rd %y, %o0 ! get lower half of product
|
1: rd %y, %o0 ! get lower half of product
|
||||||
retl
|
retl
|
||||||
addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0
|
addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0
|
||||||
#else
|
#else
|
||||||
/* Faster code from tege@sics.se. */
|
/* Faster code from tege@sics.se. */
|
||||||
sra %o1, 31, %o2 ! make mask from sign bit
|
sra %o1, 31, %o2 ! make mask from sign bit
|
||||||
and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1
|
and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1
|
||||||
rd %y, %o0 ! get lower half of product
|
rd %y, %o0 ! get lower half of product
|
||||||
retl
|
retl
|
||||||
addcc %o4, %o2, %o1 ! add compensation and put upper half in place
|
addcc %o4, %o2, %o1 ! add compensation and put upper half in place
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Lmul_shortway:
|
LOC(mul_shortway):
|
||||||
/*
|
/*
|
||||||
* Short multiply. 12 steps, followed by a final shift step.
|
* Short multiply. 12 steps, followed by a final shift step.
|
||||||
* The resulting bits are off by 12 and (32-12) = 20 bit positions,
|
* The resulting bits are off by 12 and (32-12) = 20 bit positions,
|
||||||
@ -150,4 +150,6 @@ Lmul_shortway:
|
|||||||
srl %o5, 20, %o5 ! shift low bits right 20
|
srl %o5, 20, %o5 ! shift low bits right 20
|
||||||
or %o5, %o0, %o0
|
or %o5, %o0, %o0
|
||||||
retl
|
retl
|
||||||
addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
|
addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
|
||||||
|
|
||||||
|
END(.umul)
|
||||||
|
@ -37,16 +37,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "sysdep.h"
|
#include <sysdep.h>
|
||||||
#ifdef __linux__
|
|
||||||
#include <asm/traps.h>
|
|
||||||
#else
|
|
||||||
#ifdef __svr4__
|
|
||||||
#include <sys/trap.h>
|
#include <sys/trap.h>
|
||||||
#else
|
|
||||||
#include <machine/trap.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ENTRY(.urem)
|
ENTRY(.urem)
|
||||||
|
|
||||||
@ -63,11 +55,11 @@ ENTRY(.urem)
|
|||||||
|
|
||||||
1:
|
1:
|
||||||
cmp %o3, %o5 ! if %o1 exceeds %o0, done
|
cmp %o3, %o5 ! if %o1 exceeds %o0, done
|
||||||
blu Lgot_result ! (and algorithm fails otherwise)
|
blu LOC(got_result) ! (and algorithm fails otherwise)
|
||||||
clr %o2
|
clr %o2
|
||||||
sethi %hi(1 << (32 - 4 - 1)), %g1
|
sethi %hi(1 << (32 - 4 - 1)), %g1
|
||||||
cmp %o3, %g1
|
cmp %o3, %g1
|
||||||
blu Lnot_really_big
|
blu LOC(not_really_big)
|
||||||
clr %o4
|
clr %o4
|
||||||
|
|
||||||
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
|
||||||
@ -78,15 +70,15 @@ ENTRY(.urem)
|
|||||||
1:
|
1:
|
||||||
cmp %o5, %g1
|
cmp %o5, %g1
|
||||||
bgeu 3f
|
bgeu 3f
|
||||||
mov 1, %g7
|
mov 1, %g2
|
||||||
sll %o5, 4, %o5
|
sll %o5, 4, %o5
|
||||||
b 1b
|
b 1b
|
||||||
add %o4, 1, %o4
|
add %o4, 1, %o4
|
||||||
|
|
||||||
! Now compute %g7.
|
! Now compute %g2.
|
||||||
2: addcc %o5, %o5, %o5
|
2: addcc %o5, %o5, %o5
|
||||||
bcc Lnot_too_big
|
bcc LOC(not_too_big)
|
||||||
add %g7, 1, %g7
|
add %g2, 1, %g2
|
||||||
|
|
||||||
! We get here if the %o1 overflowed while shifting.
|
! We get here if the %o1 overflowed while shifting.
|
||||||
! This means that %o3 has the high-order bit set.
|
! This means that %o3 has the high-order bit set.
|
||||||
@ -94,20 +86,20 @@ ENTRY(.urem)
|
|||||||
sll %g1, 4, %g1 ! high order bit
|
sll %g1, 4, %g1 ! high order bit
|
||||||
srl %o5, 1, %o5 ! rest of %o5
|
srl %o5, 1, %o5 ! rest of %o5
|
||||||
add %o5, %g1, %o5
|
add %o5, %g1, %o5
|
||||||
b Ldo_single_div
|
b LOC(do_single_div)
|
||||||
sub %g7, 1, %g7
|
sub %g2, 1, %g2
|
||||||
|
|
||||||
Lnot_too_big:
|
LOC(not_too_big):
|
||||||
3: cmp %o5, %o3
|
3: cmp %o5, %o3
|
||||||
blu 2b
|
blu 2b
|
||||||
nop
|
nop
|
||||||
be Ldo_single_div
|
be LOC(do_single_div)
|
||||||
nop
|
nop
|
||||||
/* NB: these are commented out in the V8-Sparc manual as well */
|
/* NB: these are commented out in the V8-Sparc manual as well */
|
||||||
/* (I do not understand this) */
|
/* (I do not understand this) */
|
||||||
! %o5 > %o3: went too far: back up 1 step
|
! %o5 > %o3: went too far: back up 1 step
|
||||||
! srl %o5, 1, %o5
|
! srl %o5, 1, %o5
|
||||||
! dec %g7
|
! dec %g2
|
||||||
! do single-bit divide steps
|
! do single-bit divide steps
|
||||||
!
|
!
|
||||||
! We have to be careful here. We know that %o3 >= %o5, so we can do the
|
! We have to be careful here. We know that %o3 >= %o5, so we can do the
|
||||||
@ -116,15 +108,15 @@ ENTRY(.urem)
|
|||||||
! order bit set in the first step, just falling into the regular
|
! order bit set in the first step, just falling into the regular
|
||||||
! division loop will mess up the first time around.
|
! division loop will mess up the first time around.
|
||||||
! So we unroll slightly...
|
! So we unroll slightly...
|
||||||
Ldo_single_div:
|
LOC(do_single_div):
|
||||||
subcc %g7, 1, %g7
|
subcc %g2, 1, %g2
|
||||||
bl Lend_regular_divide
|
bl LOC(end_regular_divide)
|
||||||
nop
|
nop
|
||||||
sub %o3, %o5, %o3
|
sub %o3, %o5, %o3
|
||||||
mov 1, %o2
|
mov 1, %o2
|
||||||
b Lend_single_divloop
|
b LOC(end_single_divloop)
|
||||||
nop
|
nop
|
||||||
Lsingle_divloop:
|
LOC(single_divloop):
|
||||||
sll %o2, 1, %o2
|
sll %o2, 1, %o2
|
||||||
bl 1f
|
bl 1f
|
||||||
srl %o5, 1, %o5
|
srl %o5, 1, %o5
|
||||||
@ -136,217 +128,219 @@ ENTRY(.urem)
|
|||||||
add %o3, %o5, %o3
|
add %o3, %o5, %o3
|
||||||
sub %o2, 1, %o2
|
sub %o2, 1, %o2
|
||||||
2:
|
2:
|
||||||
Lend_single_divloop:
|
LOC(end_single_divloop):
|
||||||
subcc %g7, 1, %g7
|
subcc %g2, 1, %g2
|
||||||
bge Lsingle_divloop
|
bge LOC(single_divloop)
|
||||||
tst %o3
|
tst %o3
|
||||||
b,a Lend_regular_divide
|
b,a LOC(end_regular_divide)
|
||||||
|
|
||||||
Lnot_really_big:
|
LOC(not_really_big):
|
||||||
1:
|
1:
|
||||||
sll %o5, 4, %o5
|
sll %o5, 4, %o5
|
||||||
cmp %o5, %o3
|
cmp %o5, %o3
|
||||||
bleu 1b
|
bleu 1b
|
||||||
addcc %o4, 1, %o4
|
addcc %o4, 1, %o4
|
||||||
be Lgot_result
|
be LOC(got_result)
|
||||||
sub %o4, 1, %o4
|
sub %o4, 1, %o4
|
||||||
|
|
||||||
tst %o3 ! set up for initial iteration
|
tst %o3 ! set up for initial iteration
|
||||||
Ldivloop:
|
LOC(divloop):
|
||||||
sll %o2, 4, %o2
|
sll %o2, 4, %o2
|
||||||
! depth 1, accumulated bits 0
|
! depth 1, accumulated bits 0
|
||||||
bl L.1.16
|
bl LOC(1.16)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 2, accumulated bits 1
|
! depth 2, accumulated bits 1
|
||||||
bl L.2.17
|
bl LOC(2.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits 3
|
! depth 3, accumulated bits 3
|
||||||
bl L.3.19
|
bl LOC(3.19)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 7
|
! depth 4, accumulated bits 7
|
||||||
bl L.4.23
|
bl LOC(4.23)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (7*2+1), %o2
|
add %o2, (7*2+1), %o2
|
||||||
|
|
||||||
L.4.23:
|
LOC(4.23):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (7*2-1), %o2
|
add %o2, (7*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.19:
|
LOC(3.19):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 5
|
! depth 4, accumulated bits 5
|
||||||
bl L.4.21
|
bl LOC(4.21)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (5*2+1), %o2
|
add %o2, (5*2+1), %o2
|
||||||
|
|
||||||
L.4.21:
|
LOC(4.21):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (5*2-1), %o2
|
add %o2, (5*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.2.17:
|
LOC(2.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits 1
|
! depth 3, accumulated bits 1
|
||||||
bl L.3.17
|
bl LOC(3.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 3
|
! depth 4, accumulated bits 3
|
||||||
bl L.4.19
|
bl LOC(4.19)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (3*2+1), %o2
|
add %o2, (3*2+1), %o2
|
||||||
|
|
||||||
L.4.19:
|
LOC(4.19):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (3*2-1), %o2
|
add %o2, (3*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.17:
|
LOC(3.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits 1
|
! depth 4, accumulated bits 1
|
||||||
bl L.4.17
|
bl LOC(4.17)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (1*2+1), %o2
|
add %o2, (1*2+1), %o2
|
||||||
|
|
||||||
L.4.17:
|
LOC(4.17):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (1*2-1), %o2
|
add %o2, (1*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.1.16:
|
LOC(1.16):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 2, accumulated bits -1
|
! depth 2, accumulated bits -1
|
||||||
bl L.2.15
|
bl LOC(2.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits -1
|
! depth 3, accumulated bits -1
|
||||||
bl L.3.15
|
bl LOC(3.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -1
|
! depth 4, accumulated bits -1
|
||||||
bl L.4.15
|
bl LOC(4.15)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-1*2+1), %o2
|
add %o2, (-1*2+1), %o2
|
||||||
|
|
||||||
L.4.15:
|
LOC(4.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-1*2-1), %o2
|
add %o2, (-1*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.15:
|
LOC(3.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -3
|
! depth 4, accumulated bits -3
|
||||||
bl L.4.13
|
bl LOC(4.13)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-3*2+1), %o2
|
add %o2, (-3*2+1), %o2
|
||||||
|
|
||||||
L.4.13:
|
LOC(4.13):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-3*2-1), %o2
|
add %o2, (-3*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
L.2.15:
|
LOC(2.15):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 3, accumulated bits -3
|
! depth 3, accumulated bits -3
|
||||||
bl L.3.13
|
bl LOC(3.13)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -5
|
! depth 4, accumulated bits -5
|
||||||
bl L.4.11
|
bl LOC(4.11)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-5*2+1), %o2
|
add %o2, (-5*2+1), %o2
|
||||||
|
|
||||||
L.4.11:
|
LOC(4.11):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-5*2-1), %o2
|
add %o2, (-5*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
L.3.13:
|
LOC(3.13):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
! depth 4, accumulated bits -7
|
! depth 4, accumulated bits -7
|
||||||
bl L.4.9
|
bl LOC(4.9)
|
||||||
srl %o5,1,%o5
|
srl %o5,1,%o5
|
||||||
! remainder is positive
|
! remainder is positive
|
||||||
subcc %o3,%o5,%o3
|
subcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-7*2+1), %o2
|
add %o2, (-7*2+1), %o2
|
||||||
|
|
||||||
L.4.9:
|
LOC(4.9):
|
||||||
! remainder is negative
|
! remainder is negative
|
||||||
addcc %o3,%o5,%o3
|
addcc %o3,%o5,%o3
|
||||||
b 9f
|
b 9f
|
||||||
add %o2, (-7*2-1), %o2
|
add %o2, (-7*2-1), %o2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
9:
|
9:
|
||||||
Lend_regular_divide:
|
LOC(end_regular_divide):
|
||||||
subcc %o4, 1, %o4
|
subcc %o4, 1, %o4
|
||||||
bge Ldivloop
|
bge LOC(divloop)
|
||||||
tst %o3
|
tst %o3
|
||||||
bl,a Lgot_result
|
bl,a LOC(got_result)
|
||||||
! non-restoring fixup here (one instruction only!)
|
! non-restoring fixup here (one instruction only!)
|
||||||
add %o3, %o1, %o3
|
add %o3, %o1, %o3
|
||||||
|
|
||||||
|
|
||||||
Lgot_result:
|
LOC(got_result):
|
||||||
|
|
||||||
retl
|
retl
|
||||||
mov %o3, %o0
|
mov %o3, %o0
|
||||||
|
|
||||||
|
END(.urem)
|
||||||
|
@ -220,6 +220,13 @@ elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc)
|
|||||||
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
|
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
|
||||||
#define ELF_MACHINE_PLTREL_OVERLAP 1
|
#define ELF_MACHINE_PLTREL_OVERLAP 1
|
||||||
|
|
||||||
|
/* The return value from dl-runtime's fixup, if it should be special. */
|
||||||
|
#define ELF_FIXUP_RETURN_VALUE(map, result) \
|
||||||
|
((map)->l_info[DT_SPARC(PLTFMT)] \
|
||||||
|
&& (map)->l_info[DT_SPARC(PLTFMT)]->d_un.d_val == 2 \
|
||||||
|
? (result) + (map)->l_info[DT_PLTGOT]->d_un.d_ptr + (map)->l_addr \
|
||||||
|
: (result))
|
||||||
|
|
||||||
/* Set up the loaded object described by L so its unrelocated PLT
|
/* Set up the loaded object described by L so its unrelocated PLT
|
||||||
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||||
|
|
||||||
@ -232,10 +239,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
|||||||
if (l->l_info[DT_JMPREL] && lazy)
|
if (l->l_info[DT_JMPREL] && lazy)
|
||||||
{
|
{
|
||||||
got = (Elf64_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
|
got = (Elf64_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
|
||||||
got[1] = (Elf64_Addr) l; /* Identify this shared object. */
|
|
||||||
/* This function will get called to fix up the GOT entry indicated by
|
/* This function will get called to fix up the GOT entry indicated by
|
||||||
the offset on the stack, and then jump to the resolved address. */
|
the offset on the stack, and then jump to the resolved address. */
|
||||||
got[2] = (Elf64_Addr) &_dl_runtime_resolve;
|
got[1] = (Elf64_Addr) &_dl_runtime_resolve;
|
||||||
|
got[2] = (Elf64_Addr) l; /* Identify this shared object. */
|
||||||
}
|
}
|
||||||
|
|
||||||
return lazy;
|
return lazy;
|
||||||
@ -248,9 +255,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
|||||||
.type _dl_runtime_resolve, @function
|
.type _dl_runtime_resolve, @function
|
||||||
_dl_runtime_resolve:
|
_dl_runtime_resolve:
|
||||||
save %sp, -160, %sp
|
save %sp, -160, %sp
|
||||||
mov %g5, %o0
|
mov %g1, %o0
|
||||||
call fixup
|
call fixup
|
||||||
mov %g6, %o1
|
mov %g2, %o1
|
||||||
jmp %o0
|
jmp %o0
|
||||||
restore
|
restore
|
||||||
.size _dl_runtime_resolve, .-_dl_runtime_resolve
|
.size _dl_runtime_resolve, .-_dl_runtime_resolve
|
||||||
|
@ -41,13 +41,11 @@
|
|||||||
|
|
||||||
/* Now two recommended cw */
|
/* Now two recommended cw */
|
||||||
|
|
||||||
/* Linux default:
|
/* Linux and IEEE default:
|
||||||
- extended precision
|
- extended precision
|
||||||
- rounding to nearest
|
- rounding to nearest
|
||||||
- no exceptions */
|
- no exceptions */
|
||||||
#define _FPU_DEFAULT 0x0
|
#define _FPU_DEFAULT 0x0
|
||||||
|
|
||||||
/* IEEE: same as above */
|
|
||||||
#define _FPU_IEEE 0x0
|
#define _FPU_IEEE 0x0
|
||||||
|
|
||||||
/* Type of the control word. */
|
/* Type of the control word. */
|
||||||
|
@ -311,11 +311,11 @@ static inline void set_segment(
|
|||||||
|
|
||||||
/* Now, reload all segment registers so the limit takes effect. */
|
/* Now, reload all segment registers so the limit takes effect. */
|
||||||
|
|
||||||
asm volatile( "movw %%ds,%0 ; movw %0,%%ds
|
asm volatile( "movw %%ds,%0 ; movw %0,%%ds\n"
|
||||||
movw %%es,%0 ; movw %0,%%es
|
"movw %%es,%0 ; movw %0,%%es\n"
|
||||||
movw %%fs,%0 ; movw %0,%%fs
|
"movw %%fs,%0 ; movw %0,%%fs\n"
|
||||||
movw %%gs,%0 ; movw %0,%%gs
|
"movw %%gs,%0 ; movw %0,%%gs\n"
|
||||||
movw %%ss,%0 ; movw %0,%%ss"
|
"movw %%ss,%0 ; movw %0,%%ss"
|
||||||
: "=r" (tmp_segment)
|
: "=r" (tmp_segment)
|
||||||
: "0" (tmp_segment)
|
: "0" (tmp_segment)
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 1994, 1996 Free Software Foundation, Inc.
|
/* Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
|
||||||
On-Line Applications Research Corporation.
|
On-Line Applications Research Corporation.
|
||||||
@ -157,10 +157,10 @@ struct i80960ca_ctltbl {
|
|||||||
|
|
||||||
#define clear_intr( xint ) \
|
#define clear_intr( xint ) \
|
||||||
{ register unsigned32 _xint=(xint); \
|
{ register unsigned32 _xint=(xint); \
|
||||||
asm volatile( "loop_til_cleared:
|
asm volatile( "loop_til_cleared:" \
|
||||||
clrbit %0,sf0,sf0 ; \
|
" clrbit %0,sf0,sf0 ;" \
|
||||||
bbs %0,sf0,loop_til_cleared" \
|
" bbs %0,sf0,loop_til_cleared" \
|
||||||
: "=d" (_xint) : "0" (_xint) ); \
|
: "=d" (_xint) : "0" (_xint) ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define reload_ctl_group( group ) \
|
#define reload_ctl_group( group ) \
|
||||||
|
@ -50,7 +50,7 @@ static void
|
|||||||
init (int argc, char **argv, char **envp)
|
init (int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
extern int __personality (int);
|
extern int __personality (int);
|
||||||
extern void __getopt_clean_environment (void);
|
extern void __getopt_clean_environment (char **);
|
||||||
|
|
||||||
/* We must not call `personality' twice. */
|
/* We must not call `personality' twice. */
|
||||||
if (!__libc_multiple_libcs)
|
if (!__libc_multiple_libcs)
|
||||||
@ -74,7 +74,7 @@ init (int argc, char **argv, char **envp)
|
|||||||
__libc_init (argc, argv, envp);
|
__libc_init (argc, argv, envp);
|
||||||
|
|
||||||
/* This is a hack to make the special getopt in GNU libc working. */
|
/* This is a hack to make the special getopt in GNU libc working. */
|
||||||
__getopt_clean_environment ();
|
__getopt_clean_environment (envp);
|
||||||
|
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
__libc_global_ctors ();
|
__libc_global_ctors ();
|
||||||
|
@ -74,24 +74,19 @@ ENTRY(____sparc_signal_trampoline)
|
|||||||
1:
|
1:
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
/* Save return address */
|
/* Save return address */
|
||||||
mov %o7,%o4
|
mov %o7,%o5
|
||||||
___sxx:
|
11: call 12f
|
||||||
call ___syy
|
sethi %hi(_GLOBAL_OFFSET_TABLE_-(11b-.)),%o4
|
||||||
nop
|
12: or %o5,%lo(_GLOBAL_OFFSET_TABLE_-(11b-.)),%o4
|
||||||
___syy:
|
add %o7,%o4,%o4
|
||||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
|
|
||||||
or %o5,%lo(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
|
|
||||||
add %o7,%o5,%o5
|
|
||||||
/* restore return address */
|
/* restore return address */
|
||||||
mov %o4,%o7
|
mov %o5,%o7
|
||||||
mov %o5,%o4
|
|
||||||
/* o4 has the GOT pointer */
|
/* o4 has the GOT pointer */
|
||||||
#endif
|
#endif
|
||||||
sethi %hi(C_SYMBOL_NAME(____sig_table)),%o5
|
sethi %hi(C_SYMBOL_NAME(____sig_table)),%o5
|
||||||
or %o5,%lo(C_SYMBOL_NAME(____sig_table)),%o5
|
or %o5,%lo(C_SYMBOL_NAME(____sig_table)),%o5
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
add %o5,%o4,%o4
|
ld [%o4+%o5], %o5
|
||||||
ld [%o4],%o5
|
|
||||||
#endif
|
#endif
|
||||||
sll %o0,2,%o4
|
sll %o0,2,%o4
|
||||||
add %o5,%o4,%o4
|
add %o5,%o4,%o4
|
||||||
@ -141,3 +136,5 @@ ___syy:
|
|||||||
/* if we return, sysreturn failed */
|
/* if we return, sysreturn failed */
|
||||||
mov SYS_ify(exit),%g1
|
mov SYS_ify(exit),%g1
|
||||||
t 0x10
|
t 0x10
|
||||||
|
|
||||||
|
END(____sparc_signal_trampoline)
|
||||||
|
39
sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c
Normal file
39
sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c
Normal 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)
|
@ -21,32 +21,76 @@
|
|||||||
This is done in one of two ways: either in the stack context
|
This is done in one of two ways: either in the stack context
|
||||||
of program start, or having dlopen pass them in. */
|
of program start, or having dlopen pass them in. */
|
||||||
|
|
||||||
#define SYSDEP_CALL_INIT(NAME, INIT) \
|
#include <sysdep.h>
|
||||||
void NAME (void *arg) \
|
|
||||||
{ \
|
|
||||||
int argc; \
|
|
||||||
char **argv, **envp; \
|
|
||||||
/* The next variable is only here to work around a bug in gcc <= 2.7.2.2. \
|
|
||||||
If the address would be taken inside the expression the optimizer \
|
|
||||||
would try to be too smart and throws it away. Grrr. */ \
|
|
||||||
int *dummy_addr = &_dl_starting_up; \
|
|
||||||
\
|
|
||||||
__libc_multiple_libcs = dummy_addr && !_dl_starting_up; \
|
|
||||||
\
|
|
||||||
if (!__libc_multiple_libcs) \
|
|
||||||
{ \
|
|
||||||
argc = *(int *) arg; \
|
|
||||||
argv = (char **) (arg + 4); \
|
|
||||||
envp = &argv[argc+1]; \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
{ \
|
|
||||||
argc = (int) arg; \
|
|
||||||
argv = ((char ***) &arg)[1]; \
|
|
||||||
envp = ((char ***) &arg)[2]; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
INIT (argc, argv, envp); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#define __S1(x) #x
|
||||||
|
#define __S(x) __S1(x)
|
||||||
|
|
||||||
|
#ifdef PIC
|
||||||
|
|
||||||
|
#define SYSDEP_CALL_INIT(NAME, INIT) asm("\
|
||||||
|
.weak _dl_starting_up
|
||||||
|
.global " #NAME "
|
||||||
|
.type " #NAME ",@function
|
||||||
|
" #NAME ":
|
||||||
|
save %sp, -64, %sp
|
||||||
|
1: call 11f
|
||||||
|
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
|
||||||
|
11: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
|
||||||
|
add %l7, %o7, %l7
|
||||||
|
/* Are we a dynamic libc being loaded into a static program? */
|
||||||
|
sethi %hi(_dl_starting_up), %l2
|
||||||
|
or %l2, %lo(_dl_starting_up), %l2
|
||||||
|
ld [%l7+%l2], %l2
|
||||||
|
cmp %l2, 0
|
||||||
|
beq 3f
|
||||||
|
sethi %hi(__libc_multiple_libcs), %l3
|
||||||
|
ld [%l2], %l2
|
||||||
|
subcc %g0, %l2, %g0
|
||||||
|
subx %g0, -1, %l2
|
||||||
|
3: or %l3, %lo(__libc_multiple_libcs), %l3
|
||||||
|
ld [%l7+%l3], %l3
|
||||||
|
cmp %l2, 0
|
||||||
|
st %l2, [%l3]
|
||||||
|
/* If so, argc et al are in %o0-%o2 already. Otherwise, load them. */
|
||||||
|
bnz " #INIT "
|
||||||
|
restore
|
||||||
|
ld [%sp+22*4], %o0
|
||||||
|
add %sp, 23*4, %o1
|
||||||
|
sll %o0, 2, %o2
|
||||||
|
add %o2, %o1, %o2
|
||||||
|
ba " #INIT "
|
||||||
|
add %o2, 4, %o2
|
||||||
|
.size "#NAME ", .-" #NAME);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define SYSDEP_CALL_INIT(NAME, INIT) asm("\
|
||||||
|
.weak _dl_starting_up
|
||||||
|
.global " #NAME "
|
||||||
|
.type " #NAME ",@function
|
||||||
|
" #NAME ":
|
||||||
|
/* Are we a dynamic libc being loaded into a static program? */
|
||||||
|
sethi %hi(_dl_starting_up), %g2
|
||||||
|
or %g2, %lo(_dl_starting_up), %g2
|
||||||
|
cmp %g2, 0
|
||||||
|
beq 3f
|
||||||
|
sethi %hi(__libc_multiple_libcs), %g3
|
||||||
|
ld [%g4+%g2], %g2
|
||||||
|
subcc %g0, %g2, %g0
|
||||||
|
subx %g0, -1, %g2
|
||||||
|
3: or %g3, %lo(__libc_multiple_libcs), %g3
|
||||||
|
cmp %g2, 0
|
||||||
|
st %g2, [%g3+%g4]
|
||||||
|
/* If so, argc et al are in %o0-%o2 already. Otherwise, load them. */
|
||||||
|
bnz " #INIT "
|
||||||
|
nop
|
||||||
|
ld [%sp+22*4], %o0
|
||||||
|
add %sp, 23*4, %o1
|
||||||
|
sll %o0, 2, %o2
|
||||||
|
add %o2, %o1, %o2
|
||||||
|
ba " #INIT "
|
||||||
|
add %o2, 4, %o2
|
||||||
|
.size "#NAME ", .-" #NAME);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -36,44 +36,51 @@
|
|||||||
/* Linux/SPARC uses a different trap number */
|
/* Linux/SPARC uses a different trap number */
|
||||||
#undef PSEUDO
|
#undef PSEUDO
|
||||||
#undef ENTRY
|
#undef ENTRY
|
||||||
|
#undef END
|
||||||
|
#undef LOC
|
||||||
|
|
||||||
#define ENTRY(name) \
|
#define ENTRY(name) \
|
||||||
.global C_SYMBOL_NAME(name); \
|
.global C_SYMBOL_NAME(name); \
|
||||||
.align 2;\
|
.align 4;\
|
||||||
C_LABEL(name);\
|
C_LABEL(name);\
|
||||||
.type name,@function;
|
.type name,@function;
|
||||||
|
|
||||||
|
#define END(name) \
|
||||||
|
.size name, . - name
|
||||||
|
|
||||||
|
#define LOC(name) . ## L ## name
|
||||||
|
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
#define SYSCALL_ERROR_HANDLER \
|
#define SYSCALL_ERROR_HANDLER \
|
||||||
.global C_SYMBOL_NAME(__errno_location);\
|
.global C_SYMBOL_NAME(__errno_location); \
|
||||||
.type C_SYMBOL_NAME(__errno_location),@function;\
|
.type C_SYMBOL_NAME(__errno_location),@function; \
|
||||||
save %sp,-96,%sp;\
|
save %sp,-96,%sp; \
|
||||||
call __errno_location;\
|
call __errno_location; \
|
||||||
nop;\
|
nop; \
|
||||||
st %i0,[%o0];\
|
st %i0,[%o0]; \
|
||||||
restore;\
|
restore; \
|
||||||
retl;\
|
retl; \
|
||||||
mov -1,%o0;
|
mov -1,%o0;
|
||||||
#else
|
#else
|
||||||
#define SYSCALL_ERROR_HANDLER \
|
#define SYSCALL_ERROR_HANDLER \
|
||||||
save %sp,-96,%sp; \
|
save %sp,-96,%sp; \
|
||||||
call __errno_location; \
|
call __errno_location; \
|
||||||
nop; \
|
nop; \
|
||||||
st %i0,[%o0]; \
|
st %i0,[%o0]; \
|
||||||
restore; \
|
restore; \
|
||||||
retl; \
|
retl; \
|
||||||
mov -1,%o0;
|
mov -1,%o0;
|
||||||
#endif /* PIC */
|
#endif /* PIC */
|
||||||
|
|
||||||
#define PSEUDO(name, syscall_name, args) \
|
#define PSEUDO(name, syscall_name, args) \
|
||||||
.text; \
|
.text; \
|
||||||
ENTRY(name); \
|
ENTRY(name); \
|
||||||
LOADSYSCALL(syscall_name); \
|
LOADSYSCALL(syscall_name); \
|
||||||
ta 0x10; \
|
ta 0x10; \
|
||||||
bcc,a 1f; \
|
bcc,a 9000f; \
|
||||||
nop; \
|
nop; \
|
||||||
SYSCALL_ERROR_HANDLER; \
|
SYSCALL_ERROR_HANDLER; \
|
||||||
1:;
|
9000:;
|
||||||
|
|
||||||
#endif /* ASSEMBLER */
|
#endif /* ASSEMBLER */
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ typedef signed long int __int64_t;
|
|||||||
typedef unsigned long int __uint64_t;
|
typedef unsigned long int __uint64_t;
|
||||||
typedef __quad_t *__qaddr_t;
|
typedef __quad_t *__qaddr_t;
|
||||||
|
|
||||||
typedef __u_int __dev_t; /* Type of device numbers. */
|
typedef __u_long __dev_t; /* Type of device numbers. */
|
||||||
typedef __u_int __uid_t; /* Type of user identifications. */
|
typedef __u_int __uid_t; /* Type of user identifications. */
|
||||||
typedef __u_int __gid_t; /* Type of group identifications. */
|
typedef __u_int __gid_t; /* Type of group identifications. */
|
||||||
typedef __u_int __ino_t; /* Type of file serial numbers. */
|
typedef __u_int __ino_t; /* Type of file serial numbers. */
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
restore
|
restore
|
||||||
ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0
|
ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0
|
||||||
add %sp, " __S(STACK_BIAS) "+23*8, %o1
|
add %sp, " __S(STACK_BIAS) "+23*8, %o1
|
||||||
sll %o0, 3, %o2
|
sllx %o0, 3, %o2
|
||||||
add %o2, %o1, %o2
|
add %o2, %o1, %o2
|
||||||
ba " #INIT "
|
ba " #INIT "
|
||||||
add %o2, 8, %o2
|
add %o2, 8, %o2
|
||||||
@ -83,10 +83,10 @@
|
|||||||
nop
|
nop
|
||||||
ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0
|
ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0
|
||||||
add %sp, " __S(STACK_BIAS) "+23*8, %o1
|
add %sp, " __S(STACK_BIAS) "+23*8, %o1
|
||||||
sll %o0, 3, %o2
|
sllx %o0, 3, %o2
|
||||||
add %o2, %o1, %o2
|
add %o2, %o1, %o2
|
||||||
add %o2, 8, %o2
|
ba " #INIT "
|
||||||
ba,a " #INIT "
|
add %o2, 8, %o2
|
||||||
.size "#NAME ", .-" #NAME);
|
.size "#NAME ", .-" #NAME);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user