aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>1998-04-08 19:32:25 +0000
committerRichard Henderson <rth@redhat.com>1998-04-08 19:32:25 +0000
commit2242f5f6c721f4239ddd1695dfd9389e81351075 (patch)
treef686803079f4758f432c410da123ed1e8fdb9c9d
parent39da45cbe60b86e6f4d2e3ff6dff21dcb52af6de (diff)
downloadglibc-2242f5f6c721f4239ddd1695dfd9389e81351075.tar
glibc-2242f5f6c721f4239ddd1695dfd9389e81351075.tar.gz
glibc-2242f5f6c721f4239ddd1695dfd9389e81351075.tar.bz2
glibc-2242f5f6c721f4239ddd1695dfd9389e81351075.zip
Commit all Sparc 2.0 patches to date.
-rw-r--r--ChangeLog.SPARC148
-rw-r--r--elf/dl-runtime.c26
-rw-r--r--elf/do-rel.h31
-rw-r--r--elf/dynamic-link.h81
-rw-r--r--elf/elf.h76
-rw-r--r--elf/rtld.c3
-rw-r--r--shlib-versions3
-rw-r--r--sysdeps/generic/dl-sysdep.c10
-rw-r--r--sysdeps/sparc/DEFS.h4
-rw-r--r--sysdeps/sparc/Dist5
-rw-r--r--sysdeps/sparc/Implies1
-rw-r--r--sysdeps/sparc/Makefile54
-rw-r--r--sysdeps/sparc/__longjmp.S59
-rw-r--r--sysdeps/sparc/add_n.S226
-rw-r--r--sysdeps/sparc/alloca.S32
-rw-r--r--sysdeps/sparc/bsd-_setjmp.S26
-rw-r--r--sysdeps/sparc/bsd-setjmp.S26
-rw-r--r--sysdeps/sparc/dl-machine.h253
-rw-r--r--sysdeps/sparc/elf/start.S111
-rw-r--r--sysdeps/sparc/memcopy.h21
-rw-r--r--sysdeps/sparc/setjmp.S33
-rw-r--r--sysdeps/sparc/sparc32/Dist3
-rw-r--r--sysdeps/sparc/sparc32/Implies1
-rw-r--r--sysdeps/sparc/sparc32/Makefile51
-rw-r--r--sysdeps/sparc/sparc32/__longjmp.S64
-rw-r--r--sysdeps/sparc/sparc32/abort-instr.h2
-rw-r--r--sysdeps/sparc/sparc32/add_n.S238
-rw-r--r--sysdeps/sparc/sparc32/addmul_1.S (renamed from sysdeps/sparc/addmul_1.S)50
-rw-r--r--sysdeps/sparc/sparc32/alloca.S33
-rw-r--r--sysdeps/sparc/sparc32/bsd-_setjmp.S1
-rw-r--r--sysdeps/sparc/sparc32/bsd-setjmp.S1
-rw-r--r--sysdeps/sparc/sparc32/bytesex.h (renamed from sysdeps/sparc/bytesex.h)0
-rw-r--r--sysdeps/sparc/sparc32/divrem.m4 (renamed from sysdeps/sparc/divrem.m4)58
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h398
-rw-r--r--sysdeps/sparc/sparc32/dotmul.S (renamed from sysdeps/sparc/dotmul.S)12
-rw-r--r--sysdeps/sparc/sparc32/elf/Makefile4
-rw-r--r--sysdeps/sparc/sparc32/elf/start.S86
-rw-r--r--sysdeps/sparc/sparc32/fpu/fpu_control.h (renamed from sysdeps/sparc/fpu_control.h)37
-rw-r--r--sysdeps/sparc/sparc32/jmp_buf.h (renamed from sysdeps/sparc/jmp_buf.h)8
-rw-r--r--sysdeps/sparc/sparc32/lshift.S (renamed from sysdeps/sparc/lshift.S)50
-rw-r--r--sysdeps/sparc/sparc32/memcopy.h21
-rw-r--r--sysdeps/sparc/sparc32/mul_1.S (renamed from sysdeps/sparc/mul_1.S)50
-rw-r--r--sysdeps/sparc/sparc32/rem.S (renamed from sysdeps/sparc/rem.S)128
-rw-r--r--sysdeps/sparc/sparc32/rshift.S (renamed from sysdeps/sparc/rshift.S)48
-rw-r--r--sysdeps/sparc/sparc32/sdiv.S (renamed from sysdeps/sparc/sdiv.S)128
-rw-r--r--sysdeps/sparc/sparc32/setjmp.S50
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/Dist6
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/addmul_1.S (renamed from sysdeps/sparc/sparc8/addmul_1.S)85
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/dotmul.S13
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/mul_1.S (renamed from sysdeps/sparc/sparc8/mul_1.S)76
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/rem.S18
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/sdiv.S14
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/submul_1.S (renamed from sysdeps/sparc/sparc8/submul_1.S)14
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/udiv.S13
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S (renamed from sysdeps/sparc/sparc8/udiv_qrnnd.S)157
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/umul.S13
-rw-r--r--sysdeps/sparc/sparc32/sparcv8/urem.S15
-rw-r--r--sysdeps/sparc/sparc32/sub_n.S329
-rw-r--r--sysdeps/sparc/sparc32/submul_1.S (renamed from sysdeps/sparc/submul_1.S)50
-rw-r--r--sysdeps/sparc/sparc32/udiv.S (renamed from sysdeps/sparc/udiv.S)124
-rw-r--r--sysdeps/sparc/sparc32/udiv_qrnnd.S (renamed from sysdeps/sparc/udiv_qrnnd.S)89
-rw-r--r--sysdeps/sparc/sparc32/umul.S (renamed from sysdeps/sparc/umul.S)26
-rw-r--r--sysdeps/sparc/sparc32/urem.S (renamed from sysdeps/sparc/urem.S)124
-rw-r--r--sysdeps/sparc/sparc64/Implies1
-rw-r--r--sysdeps/sparc/sparc64/Makefile11
-rw-r--r--sysdeps/sparc/sparc64/add_n.S58
-rw-r--r--sysdeps/sparc/sparc64/add_n.s58
-rw-r--r--sysdeps/sparc/sparc64/addmul_1.s89
-rw-r--r--sysdeps/sparc/sparc64/bytesex.h8
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h339
-rw-r--r--sysdeps/sparc/sparc64/elf/Dist4
-rw-r--r--sysdeps/sparc/sparc64/elf/Makefile10
-rw-r--r--sysdeps/sparc/sparc64/elf/crtbegin.S69
-rw-r--r--sysdeps/sparc/sparc64/elf/crtbeginS.S1
-rw-r--r--sysdeps/sparc/sparc64/elf/crtend.S70
-rw-r--r--sysdeps/sparc/sparc64/elf/crtendS.S1
-rw-r--r--sysdeps/sparc/sparc64/elf/start.S93
-rw-r--r--sysdeps/sparc/sparc64/fpu/fpu_control.h67
-rw-r--r--sysdeps/sparc/sparc64/lshift.S96
-rw-r--r--sysdeps/sparc/sparc64/lshift.s96
-rw-r--r--sysdeps/sparc/sparc64/mul_1.s86
-rw-r--r--sysdeps/sparc/sparc64/rshift.S93
-rw-r--r--sysdeps/sparc/sparc64/rshift.s93
-rw-r--r--sysdeps/sparc/sparc64/sub_n.S55
-rw-r--r--sysdeps/sparc/sparc64/sub_n.s58
-rw-r--r--sysdeps/sparc/sparc64/submul_1.s89
-rw-r--r--sysdeps/sparc/sub_n.S311
-rw-r--r--sysdeps/sparc/sys/trap.h7
-rw-r--r--sysdeps/unix/sysv/linux/accept.S1
-rw-r--r--sysdeps/unix/sysv/linux/bind.S1
-rw-r--r--sysdeps/unix/sysv/linux/connect.S1
-rw-r--r--sysdeps/unix/sysv/linux/getpeername.S1
-rw-r--r--sysdeps/unix/sysv/linux/getsockname.S1
-rw-r--r--sysdeps/unix/sysv/linux/getsockopt.S1
-rw-r--r--sysdeps/unix/sysv/linux/listen.S1
-rw-r--r--sysdeps/unix/sysv/linux/recv.S1
-rw-r--r--sysdeps/unix/sysv/linux/recvfrom.S1
-rw-r--r--sysdeps/unix/sysv/linux/recvmsg.S1
-rw-r--r--sysdeps/unix/sysv/linux/send.S1
-rw-r--r--sysdeps/unix/sysv/linux/sendmsg.S1
-rw-r--r--sysdeps/unix/sysv/linux/sendto.S1
-rw-r--r--sysdeps/unix/sysv/linux/setsockopt.S1
-rw-r--r--sysdeps/unix/sysv/linux/shutdown.S1
-rw-r--r--sysdeps/unix/sysv/linux/socketpair.S1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/Dist4
-rw-r--r--sysdeps/unix/sysv/linux/sparc/Makefile3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S142
-rw-r--r--sysdeps/unix/sysv/linux/sparc/fcntlbits.h125
-rw-r--r--sysdeps/unix/sysv/linux/sparc/ioctls.h39
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sigaction.h55
-rw-r--r--sysdeps/unix/sysv/linux/sparc/signum.h69
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/Dist7
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/Makefile12
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/__sigtrampoline.S140
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/brk.c (renamed from sysdeps/unix/sysv/linux/sparc/brk.c)13
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/clone.S (renamed from sysdeps/unix/sysv/linux/sparc/clone.S)1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/fork.S33
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c39
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/init-first.h96
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h28
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S37
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h (renamed from sysdeps/unix/sysv/linux/sparc/profil-counter.h)13
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c (renamed from sysdeps/unix/sysv/linux/sparc/sigaction.c)57
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/socket.S (renamed from sysdeps/unix/sysv/linux/sparc/socket.S)49
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S (renamed from sysdeps/unix/sysv/linux/sparc/syscall.S)19
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.S3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h (renamed from sysdeps/unix/sysv/linux/sparc/sysdep.h)64
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/Dist7
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/Makefile4
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/__longjmp.S1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/brk.S97
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/bsd-_setjmp.S1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/bsd-setjmp.S1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/clone.S90
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/fork.S33
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S30
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/gnu/types.h108
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h92
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/jmp_buf.h21
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h22
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S48
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S37
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h26
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S33
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S64
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sigjmp.S1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/statfsbuf.h42
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S39
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list25
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.S31
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h138
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/ucontext.h67
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sys/kernel_termios.h20
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sys/trap.h7
-rw-r--r--sysdeps/unix/sysv/linux/sparc/termbits.h202
156 files changed, 5506 insertions, 2628 deletions
diff --git a/ChangeLog.SPARC b/ChangeLog.SPARC
new file mode 100644
index 0000000000..f4db013b09
--- /dev/null
+++ b/ChangeLog.SPARC
@@ -0,0 +1,148 @@
+1998-04-07 Richard Henderson <rth@cygnus.com>
+
+ * sysdeps/unix/sysv/linux/sparc/sparc32/socket.S: Revert change
+ to use ldd, since the buffer is not double-word aligned.
+ Reported by Juan Cespedes <cespedes@debian.org>.
+
+ CVS Import of 2.0.7 980406.
+
+1998-04-06 Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
+
+ * elf/elf.h (EM_SPARC64): Remove.
+ (EM_SPARC32PLUS, EM_SPARCV9): New.
+
+ * elf/dl-runtime.c (fixup): Call _dl_lookup_symbol with proper
+ DL_LOOKUP_NOPLT arg.
+
+ * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_matches_host):
+ Allow v8plus on v9 cpus.
+ (elf_machine_fixup_plt): Make _dl_hwcap usage weak.
+ (elf_machine_rela): Likewise for _dl_rtld_map.
+
+ * sysdeps/unix/sysv/linux/sparc/sparc32/clone.S: Export __clone.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/clone.S: Likewise.
+
+ * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c: Translate
+ to/from struct kernel_sigaction.
+
+ * sysdeps/unix/sysv/linux/sparc/sys/kernel_termios.h: New file.
+ Sparc needs a custom value of __KERNEL_NCCS.
+
+1998-03-26 Richard Henderson <rth@cygnus.com>
+
+ CVS Commit of lingering Sparc 2.0.x patches.
+
+ * shlib-versions: Add sparc-linux bits.
+
+ * elf/dl-runtime.c (fixup): Handle plt resolution using
+ elf_machine_fixup_plt, returning the resolved value directly.
+
+ * elf/do-rel.h (elf_dynamic_do_rel): Take arguments by addr and size
+ rather than by tag number.
+ * elf/dynamic-link.h (ELF_DYNAMIC_DO_REL): Conditionally handle
+ DT_REL including DT_JMPREL.
+
+ * elf/rtld.c (_dl_hwcap): New variable.
+ (_dl_start): Make static.
+ * sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Record _dl_hwcap.
+ Collect _dl_pagesize if not given.
+
+ Move sysdeps/sparc to sysdeps/sparc/sparc32.
+ Move sysdeps/sparc/sparc32/sparc8 to sysdeps/sparc/sparc32/sparcv8
+ Move sysdeps/unix/sysv/linux/sparc to .../sparc/sparc32
+
+ * sysdeps/sparc/sparc32/DEFS.h: Remove.
+
+ * sysdeps/sparc/sparc32/Implies: Move ieee754 ...
+ * sysdeps/sparc/Implies: ... here. New file.
+
+ * sysdeps/sparc/sparc32/Makefile (divrem*): Adjust to new location.
+
+ * sysdeps/sparc/sparc32/__longjmp.S: Don't use system reserved
+ registers. Localize label usage.
+ * sysdeps/sparc/sparc32/divrem.m4: Likewise.
+
+ * sysdeps/sparc/sparc32/add_n.S: Localize label usage.
+ * sysdeps/sparc/sparc32/addmul_1.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/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/alloca.S: Use <sysdep.h>.
+
+ * sysdeps/sparc/sparc32/bsd-_setjmp.S: Move code to setjmp.S.
+ * sysdeps/sparc/sparc32/bsd-setjmp.S: Likewise.
+ * sysdeps/sparc/sparc32/setjmp.S: Use a call for proper PIC code.
+
+ * sysdeps/sparc/sparc32/dl-machine.h (OPCODE_CALL): Fix bogus value.
+ (OPCODE_SAVE_SP): Fix offset.
+ (elf_machine_load_address): Implement it proper.
+ (ELF_MACHINE_RUNTIME_TRAMPOLINE): Likewise.
+ (elf_machine_lookup_noexec_p): New.
+ (elf_machine_lookup_noplt_p): New.
+ (ELF_MACHINE_JMP_SLOT): New.
+ (ELF_MACHINE_PLTREL_OVERLAP): New.
+ (RTLD_START): Care for _dl_skip_args.
+ (elf_machine_plt_value): New.
+ (elf_machine_fixup_plt): New.
+
+ * sysdeps/sparc/sparc32/elf/Makefile: Set ASFLAGS for PIC.
+ * sysdeps/sparc/sparc32/elf/start.S: Rewrite.
+
+ * sysdeps/sparc/sparc32/abort-instr.h: New file.
+
+ Move sysdeps/sparc/sparc32/fpu_control.h to .../fpu/fpu_control.h
+
+ * sysdeps/sparc/sparc32/fpu/fpu_control.h (_FPU_RC_DOWN, _FPU_RC_UP):
+ Swap values.
+ (_FPU_DEFAULT): Default to IEEE, ie no traps enabled.
+ (_FPU_SETCW): Correct ext asm syntax.
+ (fpu_control_t): Is SImode.
+
+ * sysdeps/sparc/sys/trap.h: New file.
+
+ * sysdeps/sparc/sparc32/sparcv8/Dist: New file.
+
+ * sysdeps/sparc/sparc32/sparcv8/addmul_1.S: Localize label usage.
+ * 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/sparcv8/dotmul.S: New file.
+ * sysdeps/sparc/sparc32/sparcv8/rem.S: Likewise.
+ * sysdeps/sparc/sparc32/sparcv8/sdiv.S: Likewise.
+ * sysdeps/sparc/sparc32/sparcv8/udiv.S: Likewise.
+ * sysdeps/sparc/sparc32/sparcv8/umul.S: Likewise.
+ * sysdeps/sparc/sparc32/sparcv8/urem.S: Likewise.
+
+ * sysdeps/unix/sysv/linux/accept.S (NARGS): Define.
+ * sysdeps/unix/sysv/linux/bind.S: Likewise.
+ * sysdeps/unix/sysv/linux/connect.S: Likewise.
+ * sysdeps/unix/sysv/linux/getpeername.S: Likewise.
+ * sysdeps/unix/sysv/linux/getsockname.S: Likewise.
+ * sysdeps/unix/sysv/linux/getsockopt.S: Likewise.
+ * sysdeps/unix/sysv/linux/listen.S: Likewise.
+ * sysdeps/unix/sysv/linux/recv.S: Likewise.
+ * sysdeps/unix/sysv/linux/recvfrom.S: Likewise.
+ * sysdeps/unix/sysv/linux/recvmsg.S: Likewise.
+ * sysdeps/unix/sysv/linux/send.S: Likewise.
+ * sysdeps/unix/sysv/linux/sendmsg.S: Likewise.
+ * sysdeps/unix/sysv/linux/sendto.S: Likewise.
+ * sysdeps/unix/sysv/linux/setsockopt.S: Likewise.
+ * sysdeps/unix/sysv/linux/shutdown.S: Likewise.
+ * sysdeps/unix/sysv/linux/socketpair.S: Likewise.
+
+ * sysdeps/unix/sysv/linux/sparc/fcntlbits.h: New file.
+ * sysdeps/unix/sysv/linux/sparc/ioctls.h: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/sigaction.h: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/signum.h: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/termbits.h: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/sys/trap.h: Likewise.
+
+ * sysdeps/sparc/sparc64/*: New files.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/*: New files.
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 088ff64c6e..52cec9b028 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -116,25 +116,27 @@ fixup (
const PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
reloc_offset);
+ const ElfW(Sym) *sym = &symtab[ELFW(R_SYM)(reloc->r_info)];
+ void * const rel_addr = (void *)(l->l_addr + reloc->r_offset);
+ ElfW(Addr) value;
/* Set up the scope to find symbols referenced by this object. */
struct link_map **scope = _dl_object_relocation_scope (l);
- {
- /* This macro is used as a callback from the elf_machine_relplt code. */
-#define RESOLVE(ref, flags) \
- (_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \
- l->l_name, flags))
-#include "dynamic-link.h"
+ /* Sanity check that we're really looking at a PLT relocation. */
+ assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
- /* Perform the specified relocation. */
- elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)]);
- }
+ /* Look up the target symbol. */
+ value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
+ l->l_name, DL_LOOKUP_NOPLT);
+ value = (sym ? value + sym->st_value : 0);
+ value = elf_machine_plt_value (l, reloc, value);
- *_dl_global_scope_end = NULL;
+ /* Fix up the plt itself. */
+ elf_machine_fixup_plt (l, reloc, rel_addr, value);
- /* Return the address that was written by the relocation. */
- return *(ElfW(Addr) *) (l->l_addr + reloc->r_offset);
+ *_dl_global_scope_end = NULL;
+ return value;
}
diff --git a/elf/do-rel.h b/elf/do-rel.h
index a7b7a60c66..2bb2f7556e 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -28,28 +28,31 @@
/* Perform the relocations in MAP on the running program image as specified
- by RELTAG, SZTAG. If LAZY is nonzero, this is the first pass on PLT
+ by RELADDR, RELSIZE. If LAZY is nonzero, this is the first pass on PLT
relocations; they should be set up to call _dl_runtime_resolve, rather
than fully resolved now. */
static inline void
-elf_dynamic_do_rel (struct link_map *map,
- int reltag, int sztag,
- int lazy)
+elf_dynamic_do_rel (struct link_map *map, ElfW(Addr) reladdr,
+ ElfW(Addr) relsize, int lazy)
{
- const ElfW(Sym) *const symtab
- = (const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
- const ElfW(Rel) *r
- = (const ElfW(Rel) *) (map->l_addr + map->l_info[reltag]->d_un.d_ptr);
- const ElfW(Rel) *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r];
+ const ElfW(Rel) *r = (const ElfW(Rel) *) (map->l_addr + reladdr);
+ const ElfW(Rel) *end = (const ElfW(Rel) *)(map->l_addr + reladdr + relsize);
if (lazy)
- /* Doing lazy PLT relocations; they need very little info. */
- for (; r < end; ++r)
- elf_machine_lazy_rel (map, r);
+ {
+ /* Doing lazy PLT relocations; they need very little info. */
+ for (; r < end; ++r)
+ elf_machine_lazy_rel (map, r);
+ }
else
- for (; r < end; ++r)
- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)]);
+ {
+ const ElfW(Sym) *const symtab =
+ (const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
+
+ for (; r < end; ++r)
+ elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)]);
+ }
}
#undef elf_dynamic_do_rel
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index da63633361..ba1958cdbc 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -70,14 +70,75 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
duplicating their code. It cannot be done in a more general function
because we must be able to completely inline. */
+/* On some machines, notably Sparc, DT_REL* includes DT_JMPREL in its
+ range. Note that according to the ELF spec, this is completely legal!
+ But conditionally define things so that on machines we know this will
+ not happen we do something more optimal. */
+
+#ifdef ELF_MACHINE_PLTREL_OVERLAP
+#define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, lazy) \
+ do { \
+ ElfW(Addr) r_addr, r_size, p_addr, p_size; \
+ if ((map)->l_info[DT_##RELOC]) \
+ { \
+ r_addr = (map)->l_info[DT_##RELOC]->d_un.d_ptr; \
+ r_size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
+ if ((map)->l_info[DT_PLTREL] && \
+ (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC) \
+ { \
+ p_addr = (map)->l_info[DT_JMPREL]->d_un.d_ptr; \
+ p_size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
+ if (r_addr <= p_addr && r_addr+r_size > p_addr) \
+ { \
+ ElfW(Addr) r2_addr, r2_size; \
+ r2_addr = p_addr+p_size; \
+ if (r2_addr < r_addr+r_size) \
+ { \
+ r2_size = r_addr+r_size - r2_addr; \
+ elf_dynamic_do_##reloc ((map), r2_addr, r2_size, 0); \
+ } \
+ r_size = p_addr - r_addr; \
+ } \
+ } \
+ \
+ elf_dynamic_do_##reloc ((map), r_addr, r_size, 0); \
+ if (p_addr) \
+ elf_dynamic_do_##reloc ((map), p_addr, p_size, (lazy)); \
+ } \
+ else if ((map)->l_info[DT_PLTREL] && \
+ (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC) \
+ { \
+ p_addr = (map)->l_info[DT_JMPREL]->d_un.d_ptr; \
+ p_size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
+ \
+ elf_dynamic_do_##reloc ((map), p_addr, p_size, (lazy)); \
+ } \
+ } while (0)
+#else
+#define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, lazy) \
+ do { \
+ if ((map)->l_info[DT_##RELOC]) \
+ { \
+ ElfW(Addr) r_addr, r_size; \
+ r_addr = (map)->l_info[DT_##RELOC]->d_un.d_ptr; \
+ r_size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
+ elf_dynamic_do_##reloc ((map), r_addr, r_size, 0); \
+ } \
+ if ((map)->l_info[DT_PLTREL] && \
+ (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC) \
+ { \
+ ElfW(Addr) p_addr, p_size; \
+ p_addr = (map)->l_info[DT_JMPREL]->d_un.d_ptr; \
+ p_size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
+ elf_dynamic_do_##reloc ((map), p_addr, p_size, (lazy)); \
+ } \
+ } while (0)
+#endif
+
#if ! ELF_MACHINE_NO_REL
#include "do-rel.h"
-#define ELF_DYNAMIC_DO_REL(map, lazy) \
- if ((map)->l_info[DT_REL]) \
- elf_dynamic_do_rel ((map), DT_REL, DT_RELSZ, 0); \
- if ((map)->l_info[DT_PLTREL] && \
- (map)->l_info[DT_PLTREL]->d_un.d_val == DT_REL) \
- elf_dynamic_do_rel ((map), DT_JMPREL, DT_PLTRELSZ, (lazy));
+#define ELF_DYNAMIC_DO_REL(map, lazy) \
+ _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy)
#else
#define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do. */
#endif
@@ -85,12 +146,8 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
#if ! ELF_MACHINE_NO_RELA
#define DO_RELA
#include "do-rel.h"
-#define ELF_DYNAMIC_DO_RELA(map, lazy) \
- if ((map)->l_info[DT_RELA]) \
- elf_dynamic_do_rela ((map), DT_RELA, DT_RELASZ, 0); \
- if ((map)->l_info[DT_PLTREL] && \
- (map)->l_info[DT_PLTREL]->d_un.d_val == DT_RELA) \
- elf_dynamic_do_rela ((map), DT_JMPREL, DT_PLTRELSZ, (lazy));
+#define ELF_DYNAMIC_DO_RELA(map, lazy) \
+ _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy)
#else
#define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do. */
#endif
diff --git a/elf/elf.h b/elf/elf.h
index 05eeb3664f..de32630c2e 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -161,10 +161,10 @@ typedef struct
#define EM_S370 9 /* Amdahl */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
-#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */
-
#define EM_PARISC 15 /* HPPA */
+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
#define EM_PPC 20 /* PowerPC */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
/* If it is necessary to assign new unofficial EM_* values, please
pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
@@ -605,6 +605,11 @@ typedef struct
#define AT_GID 13 /* Real gid */
#define AT_EGID 14 /* Effective gid */
+/* Some more special a_type values describing the hardware. */
+#define AT_PLATFORM 15 /* String identifying platform. */
+#define AT_HWCAP 16 /* Machine dependent hints about
+ processor capabilities. */
+
/* Motorola 68k specific definitions. */
/* m68k relocs. */
@@ -678,6 +683,73 @@ typedef struct
#define R_SPARC_RELATIVE 22 /* Adjust by program base */
#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */
+/* Sparc64 additional relocs. */
+
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_64 32
+#define R_SPARC_OLO10 33
+#define R_SPARC_HH22 34
+#define R_SPARC_HM10 35
+#define R_SPARC_LM22 36
+#define R_SPARC_PC_HH22 37
+#define R_SPARC_PC_HM10 38
+#define R_SPARC_PC_LM22 39
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+#define R_SPARC_DISP64 46
+#define R_SPARC_PLT64 47
+#define R_SPARC_HIX22 48
+#define R_SPARC_LOX10 49
+#define R_SPARC_H44 50
+#define R_SPARC_M44 51
+#define R_SPARC_L44 52
+#define R_SPARC_REGISTER 53
+#define R_SPARC_UA64 54
+#define R_SPARC_UA16 55
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn. */
+
+#define DT_SPARC_REGISTER 0x70000001
+#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
+#define HWCAP_SPARC_V9 16
+
+/* Values for Elf64_Ehdr.e_flags. */
+
+#define EF_SPARCV9_MM 3
+#define EF_SPARCV9_TSO 0
+#define EF_SPARCV9_PSO 1
+#define EF_SPARCV9_RMO 2
+#define EF_SPARC_EXT_MASK 0xFFFF00
+#define EF_SPARC_SUN_US1 0x000200
+#define EF_SPARC_HAL_R1 0x000400
+
+/* For Sparc64, special section indices. */
+
+#define SHN_SPARC_BEFORE 0xff00
+#define SHN_SPARC_AFTER 0xff01
+
+/* For Sparc64, special section flags. */
+
+#define SHF_SPARC_EXCLUDE 0x80000000
+#define SHF_SPARC_ORDERED 0x40000000
+
/* MIPS R3000 specific definitions. */
/* Legal values for e_flags field of Elf32_Ehdr. */
diff --git a/elf/rtld.c b/elf/rtld.c
index f7b76ada8d..fc38ade54f 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -52,6 +52,7 @@ int _dl_argc;
char **_dl_argv;
const char *_dl_rpath;
const char *_dl_library_path;
+unsigned long _dl_hwcap;
/* Set nonzero during loading and initialization of executable and
libraries, cleared before the executable's entry point runs. This
@@ -74,7 +75,7 @@ RTLD_START
#error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START"
#endif
-ElfW(Addr)
+static ElfW(Addr)
_dl_start (void *arg)
{
struct link_map bootstrap_map;
diff --git a/shlib-versions b/shlib-versions
index 3ad220d625..4a8e9738a2 100644
--- a/shlib-versions
+++ b/shlib-versions
@@ -13,11 +13,13 @@ i.86-.*-.* libm=6
m68k-.*-.* libm=6
alpha-.*-linux.* libm=6.1
alpha-.*-.* libm=6
+sparc-.*-.* libm=6
# We provide libc.so.6 for Linux kernel versions 2.0 and later.
i.86-.*-linux.* libc=6
m68k-.*-linux.* libc=6
alpha-.*-linux.* libc=6.1
+sparc-.*-linux.* libc=6
# libmachuser.so.1 corresponds to mach/*.defs as of Utah's UK22 release.
.*-.*-gnu-gnu.* libmachuser=1
@@ -31,6 +33,7 @@ alpha-.*-linux.* libc=6.1
# The dynamic loader also requires different names.
i.86-.*-linux.* ld=ld-linux.so.2
alpha-.*-linux.* ld=ld-linux.so.2
+sparc-.*-linux.* ld=ld-linux.so.2
# We use the ELF ABI standard name for the default.
.*-.*-.* ld=ld.so.1
diff --git a/sysdeps/generic/dl-sysdep.c b/sysdeps/generic/dl-sysdep.c
index e9fbcdf4bc..01c4527151 100644
--- a/sysdeps/generic/dl-sysdep.c
+++ b/sysdeps/generic/dl-sysdep.c
@@ -32,6 +32,7 @@ extern int _dl_argc;
extern char **_dl_argv;
extern char **_environ;
extern size_t _dl_pagesize;
+extern unsigned long _dl_hwcap;
extern void _end;
extern void _start (void);
@@ -94,6 +95,9 @@ _dl_sysdep_start (void **start_argptr,
case AT_EGID:
egid = av->a_un.a_val;
break;
+ case AT_HWCAP:
+ _dl_hwcap = av->a_un.a_val;
+ break;
}
/* Linux doesn't provide us with any of these values on the stack
@@ -108,6 +112,9 @@ _dl_sysdep_start (void **start_argptr,
__libc_enable_secure = uid != euid || gid != egid;
+ if (_dl_pagesize == 0)
+ _dl_pagesize = __getpagesize ();
+
#ifdef DL_SYSDEP_INIT
DL_SYSDEP_INIT;
#endif
@@ -119,9 +126,8 @@ _dl_sysdep_start (void **start_argptr,
will consume the rest of this page, so tell the kernel to move the
break up that far. When the user program examines its break, it
will see this new value and not clobber our data. */
- size_t pg = __getpagesize ();
- __sbrk (pg - ((&_end - (void *) 0) & (pg - 1)));
+ __sbrk (_dl_pagesize - ((&_end - (void *) 0) & (_dl_pagesize - 1)));
}
(*dl_main) (phdr, phnum, &user_entry);
diff --git a/sysdeps/sparc/DEFS.h b/sysdeps/sparc/DEFS.h
deleted file mode 100644
index ef6966319f..0000000000
--- a/sysdeps/sparc/DEFS.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define FUNC(name) \
- .global name; \
- .align 4; \
- name:
diff --git a/sysdeps/sparc/Dist b/sysdeps/sparc/Dist
index ef6c44f78e..7832507772 100644
--- a/sysdeps/sparc/Dist
+++ b/sysdeps/sparc/Dist
@@ -1,4 +1 @@
-DEFS.h
-dotmul.S umul.S
-divrem.m4 sdiv.S udiv.S rem.S urem.S
-alloca.S
+sys/trap.h
diff --git a/sysdeps/sparc/Implies b/sysdeps/sparc/Implies
index 8a2007c5ce..da719e1707 100644
--- a/sysdeps/sparc/Implies
+++ b/sysdeps/sparc/Implies
@@ -1,3 +1,2 @@
-wordsize-32
# SPARC uses IEEE 754 floating point.
ieee754
diff --git a/sysdeps/sparc/Makefile b/sysdeps/sparc/Makefile
index deec2f8145..e55e461423 100644
--- a/sysdeps/sparc/Makefile
+++ b/sysdeps/sparc/Makefile
@@ -1,51 +1,3 @@
-# Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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.
-
-ifeq ($(subdir),gnulib)
-routines = dotmul umul $(divrem) alloca
-endif # gnulib
-
-# We distribute these files, even though they are generated,
-# so as to avoid the need for a functioning m4 to build the library.
-divrem := sdiv udiv rem urem
-
-+divrem-NAME-sdiv := div
-+divrem-NAME-udiv := udiv
-+divrem-NAME-rem := rem
-+divrem-NAME-urem := urem
-+divrem-NAME = $(+divrem-NAME-$(basename $(notdir $@)))
-+divrem-OP-div := div
-+divrem-OP-udiv := div
-+divrem-OP-rem := rem
-+divrem-OP-urem := rem
-+divrem-S-div := true
-+divrem-S-rem := true
-+divrem-S-udiv := false
-+divrem-S-urem := false
-$(divrem:%=$(sysdep_dir)/sparc/%.S): $(sysdep_dir)/sparc/divrem.m4
- (echo "define(NAME,\`.$(+divrem-NAME)')\
- define(OP,\`$(+divrem-OP-$(+divrem-NAME))')\
- define(S,\`$(+divrem-S-$(+divrem-NAME))')\
- /* This file is generated from divrem.m4; DO NOT EDIT! */"; \
- cat $<) | $(M4) > $@-tmp
-# Make it unwritable so noone will edit it by mistake.
- -chmod a-w $@-tmp
- mv -f $@-tmp $@
- test ! -d CVS || cvs commit -m'Regenerated from $<' $@
-
-sysdep-realclean := $(sysdep-realclean) $(divrem:%=sysdeps/sparc/%.S)
+ifeq ($(subdir),db2)
+CPPFLAGS += -DHAVE_SPINLOCKS=1 -DHAVE_ASSEM_SPARC_GCC=1
+endif
diff --git a/sysdeps/sparc/__longjmp.S b/sysdeps/sparc/__longjmp.S
deleted file mode 100644
index 5424300fe5..0000000000
--- a/sysdeps/sparc/__longjmp.S
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (C) 1991, 1993, 1996 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., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include <sysdep.h>
-
-#define _ASM 1
-#include <jmp_buf.h>
-#define ENV(reg) [%g1 + (reg * 4)]
-
-ENTRY (__longjmp)
- /* Store our arguments in global registers so we can still
- use them while unwinding frames and their register windows. */
- mov %o0, %g1 /* ENV in %g1 */
- orcc %o1, %g0, %g6 /* VAL in %g6 */
- be,a 0f /* Branch if zero; else skip delay slot. */
- mov 1, %g6 /* Delay slot only hit if zero: VAL = 1. */
-0:
-
- /* Cache target FP in register %g7. */
- ld ENV (JB_FP), %g7
-
- /* Now we will loop, unwinding the register windows up the stack
- until the restored %fp value matches the target value in %g7. */
-
-loop: cmp %fp, %g7 /* Have we reached the target frame? */
- bl,a loop /* Loop while current fp is below target. */
- restore /* Unwind register window in delay slot. */
- be,a found /* Better have hit it exactly. */
- ld ENV (JB_SP), %o0 /* Delay slot: extract target SP. */
-
-bogus: /* Get here only if the jmp_buf or stack is clobbered. */
- call C_SYMBOL_NAME (abort)
- nop
- unimp 0
-
-found: /* We have unwound register windows so %fp matches the target. */
- cmp %o0, %sp /* Check jmp_buf SP vs register window. */
- bge,a sp_ok /* Saved must not be deeper than register. */
- mov %o0, %sp /* OK, install new SP. */
- b,a bogus /* Bogus, we lose. */
-
-sp_ok: ld ENV (JB_PC), %o0 /* Extract target return PC. */
- jmp %o0 + 8 /* Return there. */
- mov %g6, %o0 /* Delay slot: set return value. */
diff --git a/sysdeps/sparc/add_n.S b/sysdeps/sparc/add_n.S
deleted file mode 100644
index 9852c256aa..0000000000
--- a/sysdeps/sparc/add_n.S
+++ /dev/null
@@ -1,226 +0,0 @@
-! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
-! sum in a third limb vector.
-
-! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-! This file is part of the GNU MP Library.
-
-! The GNU MP Library is free software; you can redistribute it and/or modify
-! it under the terms of the GNU Library General Public License as published by
-! the Free Software Foundation; either version 2 of the License, or (at your
-! option) any later version.
-
-! The GNU MP Library is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
-! License for more details.
-
-! You should have received a copy of the GNU Library General Public License
-! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
-! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-! MA 02111-1307, USA.
-
-
-! INPUT PARAMETERS
-#define res_ptr %o0
-#define s1_ptr %o1
-#define s2_ptr %o2
-#define size %o3
-
-#include "sysdep.h"
-
- .text
- .align 4
- .global C_SYMBOL_NAME(__mpn_add_n)
-C_SYMBOL_NAME(__mpn_add_n):
- xor s2_ptr,res_ptr,%g1
- andcc %g1,4,%g0
- bne L1 ! branch if alignment differs
- nop
-! ** V1a **
-L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
- be L_v1 ! if no, branch
- nop
-/* Add least significant limb separately to align res_ptr and s2_ptr */
- ld [s1_ptr],%g4
- add s1_ptr,4,s1_ptr
- ld [s2_ptr],%g2
- add s2_ptr,4,s2_ptr
- add size,-1,size
- addcc %g4,%g2,%o4
- st %o4,[res_ptr]
- add res_ptr,4,res_ptr
-L_v1: addx %g0,%g0,%o4 ! save cy in register
- cmp size,2 ! if size < 2 ...
- bl Lend2 ! ... branch to tail code
- subcc %g0,%o4,%g0 ! restore cy
-
- ld [s1_ptr+0],%g4
- addcc size,-10,size
- ld [s1_ptr+4],%g1
- ldd [s2_ptr+0],%g2
- blt Lfin1
- subcc %g0,%o4,%g0 ! restore cy
-/* Add blocks of 8 limbs until less than 8 limbs remain */
-Loop1: addxcc %g4,%g2,%o4
- ld [s1_ptr+8],%g4
- addxcc %g1,%g3,%o5
- ld [s1_ptr+12],%g1
- ldd [s2_ptr+8],%g2
- std %o4,[res_ptr+0]
- addxcc %g4,%g2,%o4
- ld [s1_ptr+16],%g4
- addxcc %g1,%g3,%o5
- ld [s1_ptr+20],%g1
- ldd [s2_ptr+16],%g2
- std %o4,[res_ptr+8]
- addxcc %g4,%g2,%o4
- ld [s1_ptr+24],%g4
- addxcc %g1,%g3,%o5
- ld [s1_ptr+28],%g1
- ldd [s2_ptr+24],%g2
- std %o4,[res_ptr+16]
- addxcc %g4,%g2,%o4
- ld [s1_ptr+32],%g4
- addxcc %g1,%g3,%o5
- ld [s1_ptr+36],%g1
- ldd [s2_ptr+32],%g2
- std %o4,[res_ptr+24]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-8,size
- add s1_ptr,32,s1_ptr
- add s2_ptr,32,s2_ptr
- add res_ptr,32,res_ptr
- bge Loop1
- subcc %g0,%o4,%g0 ! restore cy
-
-Lfin1: addcc size,8-2,size
- blt Lend1
- subcc %g0,%o4,%g0 ! restore cy
-/* Add blocks of 2 limbs until less than 2 limbs remain */
-Loope1: addxcc %g4,%g2,%o4
- ld [s1_ptr+8],%g4
- addxcc %g1,%g3,%o5
- ld [s1_ptr+12],%g1
- ldd [s2_ptr+8],%g2
- std %o4,[res_ptr+0]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-2,size
- add s1_ptr,8,s1_ptr
- add s2_ptr,8,s2_ptr
- add res_ptr,8,res_ptr
- bge Loope1
- subcc %g0,%o4,%g0 ! restore cy
-Lend1: addxcc %g4,%g2,%o4
- addxcc %g1,%g3,%o5
- std %o4,[res_ptr+0]
- addx %g0,%g0,%o4 ! save cy in register
-
- andcc size,1,%g0
- be Lret1
- subcc %g0,%o4,%g0 ! restore cy
-/* Add last limb */
- ld [s1_ptr+8],%g4
- ld [s2_ptr+8],%g2
- addxcc %g4,%g2,%o4
- st %o4,[res_ptr+8]
-
-Lret1: retl
- addx %g0,%g0,%o0 ! return carry-out from most sign. limb
-
-L1: xor s1_ptr,res_ptr,%g1
- andcc %g1,4,%g0
- bne L2
- nop
-! ** V1b **
- mov s2_ptr,%g1
- mov s1_ptr,s2_ptr
- b L0
- mov %g1,s1_ptr
-
-! ** V2 **
-/* If we come here, the alignment of s1_ptr and res_ptr as well as the
- alignment of s2_ptr and res_ptr differ. Since there are only two ways
- things can be aligned (that we care about) we now know that the alignment
- of s1_ptr and s2_ptr are the same. */
-
-L2: cmp size,1
- be Ljone
- nop
- andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
- be L_v2 ! if no, branch
- nop
-/* Add least significant limb separately to align s1_ptr and s2_ptr */
- ld [s1_ptr],%g4
- add s1_ptr,4,s1_ptr
- ld [s2_ptr],%g2
- add s2_ptr,4,s2_ptr
- add size,-1,size
- addcc %g4,%g2,%o4
- st %o4,[res_ptr]
- add res_ptr,4,res_ptr
-
-L_v2: addx %g0,%g0,%o4 ! save cy in register
- addcc size,-8,size
- blt Lfin2
- subcc %g0,%o4,%g0 ! restore cy
-/* Add blocks of 8 limbs until less than 8 limbs remain */
-Loop2: ldd [s1_ptr+0],%g2
- ldd [s2_ptr+0],%o4
- addxcc %g2,%o4,%g2
- st %g2,[res_ptr+0]
- addxcc %g3,%o5,%g3
- st %g3,[res_ptr+4]
- ldd [s1_ptr+8],%g2
- ldd [s2_ptr+8],%o4
- addxcc %g2,%o4,%g2
- st %g2,[res_ptr+8]
- addxcc %g3,%o5,%g3
- st %g3,[res_ptr+12]
- ldd [s1_ptr+16],%g2
- ldd [s2_ptr+16],%o4
- addxcc %g2,%o4,%g2
- st %g2,[res_ptr+16]
- addxcc %g3,%o5,%g3
- st %g3,[res_ptr+20]
- ldd [s1_ptr+24],%g2
- ldd [s2_ptr+24],%o4
- addxcc %g2,%o4,%g2
- st %g2,[res_ptr+24]
- addxcc %g3,%o5,%g3
- st %g3,[res_ptr+28]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-8,size
- add s1_ptr,32,s1_ptr
- add s2_ptr,32,s2_ptr
- add res_ptr,32,res_ptr
- bge Loop2
- subcc %g0,%o4,%g0 ! restore cy
-
-Lfin2: addcc size,8-2,size
- blt Lend2
- subcc %g0,%o4,%g0 ! restore cy
-Loope2: ldd [s1_ptr+0],%g2
- ldd [s2_ptr+0],%o4
- addxcc %g2,%o4,%g2
- st %g2,[res_ptr+0]
- addxcc %g3,%o5,%g3
- st %g3,[res_ptr+4]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-2,size
- add s1_ptr,8,s1_ptr
- add s2_ptr,8,s2_ptr
- add res_ptr,8,res_ptr
- bge Loope2
- subcc %g0,%o4,%g0 ! restore cy
-Lend2: andcc size,1,%g0
- be Lret2
- subcc %g0,%o4,%g0 ! restore cy
-/* Add last limb */
-Ljone: ld [s1_ptr],%g4
- ld [s2_ptr],%g2
- addxcc %g4,%g2,%o4
- st %o4,[res_ptr]
-
-Lret2: retl
- addx %g0,%g0,%o0 ! return carry-out from most sign. limb
diff --git a/sysdeps/sparc/alloca.S b/sysdeps/sparc/alloca.S
deleted file mode 100644
index 0a8718de31..0000000000
--- a/sysdeps/sparc/alloca.S
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright (C) 1994 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., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include "DEFS.h"
-
-/* Code produced by Sun's C compiler calls this function with two extra
- arguments which it makes relocatable symbols but seem always to be
- the constant 96; I have no idea what they are for. */
-
-#ifndef NO_UNDERSCORES
-#define __builtin_alloca ___builtin_alloca
-#endif
-
-FUNC (__builtin_alloca)
- sub %sp, %o0, %sp /* Push some stack space. */
- retl /* Return; the returned buffer leaves 96 */
- add %sp, 96, %o0 /* bytes of register save area at the top. */
diff --git a/sysdeps/sparc/bsd-_setjmp.S b/sysdeps/sparc/bsd-_setjmp.S
deleted file mode 100644
index 5b685d5496..0000000000
--- a/sysdeps/sparc/bsd-_setjmp.S
+++ /dev/null
@@ -1,26 +0,0 @@
-/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. Sparc version.
-Copyright (C) 1994 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., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include <sysdep.h>
-
-ENTRY (setjmp)
- sethi %hi(C_SYMBOL_NAME (__sigsetjmp)), %g1
- or %lo(C_SYMBOL_NAME (__sigsetjmp)), %g1, %g1
- jmp %g1
- mov %g0, %o1 /* Pass second argument of zero. */
diff --git a/sysdeps/sparc/bsd-setjmp.S b/sysdeps/sparc/bsd-setjmp.S
deleted file mode 100644
index b0a6326a2c..0000000000
--- a/sysdeps/sparc/bsd-setjmp.S
+++ /dev/null
@@ -1,26 +0,0 @@
-/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. Sparc version.
-Copyright (C) 1994 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., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include <sysdep.h>
-
-ENTRY (setjmp)
- sethi %hi(C_SYMBOL_NAME (__sigsetjmp)), %g1
- or %lo(C_SYMBOL_NAME (__sigsetjmp)), %g1, %g1
- jmp %g1
- mov 1, %o1 /* Pass second argument of one. */
diff --git a/sysdeps/sparc/dl-machine.h b/sysdeps/sparc/dl-machine.h
deleted file mode 100644
index b81d306c3b..0000000000
--- a/sysdeps/sparc/dl-machine.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/* Machine-dependent ELF dynamic relocation inline functions. SPARC version.
- Copyright (C) 1996, 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. */
-
-#define ELF_MACHINE_NAME "sparc"
-
-#include <assert.h>
-#include <string.h>
-#include <link.h>
-
-
-/* Some SPARC opcodes we need to use for self-modifying code. */
-#define OPCODE_NOP 0x01000000 /* nop */
-#define OPCODE_CALL 0x04000000 /* call ?; add PC-rel word address */
-#define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */
-#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
-#define OPCODE_SAVE_SP64 0x9de3bfc0 /* save %sp, -64, %sp */
-
-
-/* Return nonzero iff E_MACHINE is compatible with the running host. */
-static inline int
-elf_machine_matches_host (Elf32_Half e_machine)
-{
- switch (e_machine)
- {
- case EM_SPARC:
- return 1;
- default:
- return 0;
- }
-}
-
-
-/* Return the link-time address of _DYNAMIC. Conveniently, this is the
- first element of the GOT. This must be inlined in a function which
- uses global data. */
-static inline Elf32_Addr
-elf_machine_dynamic (void)
-{
- register Elf32_Addr *got asm ("%l7");
- return *got;
-}
-
-
-/* Return the run-time load address of the shared object. */
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
- Elf32_Addr addr;
-???
- return addr;
-}
-
-/* The `subl' insn above will contain an R_68K_RELATIVE relocation
- entry intended to insert the run-time address of the label `here'.
- 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) \
- ((dynamic_info)[DT_RELA]->d_un.d_ptr += sizeof (Elf32_Rela), \
- (dynamic_info)[DT_RELASZ]->d_un.d_val -= sizeof (Elf32_Rela))
-
-/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
- MAP is the object containing the reloc. */
-
-static inline void
-elf_machine_rela (struct link_map *map,
- const Elf32_Rela *reloc, const Elf32_Sym *sym,
- Elf32_Addr (*resolve) (const Elf32_Sym **ref,
- Elf32_Addr reloc_addr,
- int noplt))
-{
- Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset);
- Elf32_Addr loadbase;
-
- switch (ELF32_R_TYPE (reloc->r_info))
- {
- case R_SPARC_COPY:
- loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
- memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size);
- break;
- case R_SPARC_GLOB_DAT:
- case R_SPARC_32:
- loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0) :
- /* RESOLVE is null during bootstrap relocation. */
- map->l_addr);
- *reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
- + reloc->r_addend);
- break;
- case R_SPARC_JMP_SLOT:
- loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 1) :
- /* RESOLVE is null during bootstrap relocation. */
- map->l_addr);
- {
- Elf32_Addr value = ((sym ? (loadbase + sym->st_value) : 0)
- + reloc->r_addend);
- reloc_addr[1] = OPCODE_SETHI | (value >> 10);
- reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
- }
- break;
- case R_SPARC_8:
- loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
- *(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
- + reloc->r_addend);
- break;
- case R_SPARC_16:
- loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
- *(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
- + reloc->r_addend);
- break;
- case R_SPARC_32:
- loadbase = (resolve ? (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0) :
- /* RESOLVE is null during bootstrap relocation. */
- map->l_addr);
- break;
- case R_SPARC_RELATIVE:
- *reloc_addr = map->l_addr + reloc->r_addend;
- break;
- case R_SPARC_DISP8:
- loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
- *(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
- + reloc->r_addend
- - (Elf32_Addr) reloc_addr);
- break;
- case R_SPARC_DISP16:
- loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
- *(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
- + reloc->r_addend
- - (Elf32_Addr) reloc_addr);
- break;
- case R_SPARC_DISP32:
- loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
- *reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
- + reloc->r_addend
- - (Elf32_Addr) reloc_addr);
- break;
- case R_SPARC_NONE: /* Alright, Wilbur. */
- break;
- default:
- assert (! "unexpected dynamic reloc type");
- break;
- }
-}
-
-static inline void
-elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
-{
- switch (ELF32_R_TYPE (reloc->r_info))
- {
- case R_SPARC_NONE:
- break;
- case R_SPARC_JMP_SLOT:
- break;
- default:
- assert (! "unexpected PLT reloc type");
- break;
- }
-}
-
-/* Nonzero iff TYPE describes relocation of a PLT entry, so
- PLT entries should not be allowed to define the value. */
-#define elf_machine_pltrel_p(type) ((type) == R_SPARC_JMP_SLOT)
-
-/* The SPARC never uses Elf32_Rel relocations. */
-#define ELF_MACHINE_NO_REL 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)
-{
- 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] = 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:
- | 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 (???)
diff --git a/sysdeps/sparc/elf/start.S b/sysdeps/sparc/elf/start.S
deleted file mode 100644
index 6dae08bafa..0000000000
--- a/sysdeps/sparc/elf/start.S
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Startup code compliant to the ELF SPARC ABI.
-Copyright (C) 1996 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., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-/* This is the canonical entry point, usually the first thing in the text
- segment. The SVR4/SPARC ABI (NOTE: I don't actually have it) says that
- when the entry point runs, most registers' values are unspecified,
- except for:
-
- %g1 Contains a function pointer to be registered with `atexit'.
- This is how the dynamic linker arranges to have DT_FINI
- functions called for shared libraries that have been loaded
- before this code runs.
-
- %sp The stack contains the arguments and environment:
- 0(%sp) argc
- 4(%sp) argv[0]
- ...
- (4*argc)(%sp) NULL
- (4*(argc+1))(%sp) envp[0]
- ...
- NULL
-*/
-
- .text
- .align 16
- .global _start
-_start:
- /* %g1 contains the address of the shared library termination
- function, which we will register with `atexit' to be called by
- `exit'. I suspect that on some systems, and when statically
- linked, this will not be set by anything to any function
- pointer; hopefully it will be zero so we don't try to call
- random pointers. */
- orcc %g1, %g0, %o0 /* Move %g1 to %o0 while testing it. */
- be nofini
-
- /* In delay slot: clear the frame pointer. The ABI suggests this
- be done, to mark the outermost frame obviously. */
- clr %fp
-
- /* Call atexit, argument was set in %o0 above. */
- call atexit
- nop
-nofini:
-
- /* We will use some local variables in registers below. %g1 and
- the %oN registers are call-clobbered, so we can't just use them. */
-#define ARGC %l0
-#define ARGV %l1
-#define ENVP %l2
-#define TMP %l3
-
- /* Do essential libc initialization. In statically linked
- programs under the GNU Hurd, this is what sets up the
- arguments on the stack for the code below. */
- call __libc_init_first
- sethi %hi(_environ), TMP /* In delay slot: prepare to use &_environ. */
-
- /* Extract the arguments and environment as encoded on the stack
- and save them in local variables. */
- ld [%sp + 64], ARGC /* After the register save area, ARGC. */
- add %sp, 64+4, ARGV /* Next, the ARGV elements. */
- /* After ARGC words that are the ARGV elements, and a zero word,
- are the ENVP elements. Do ENVP = &ARGV[ARGC + 1]. */
- add ARGC, 1, ENVP
- sll ENVP, 2, ENVP
- add ARGV, ENVP, ENVP
- /* Store ENVP in the global variable `_environ'. */
- st [TMP + %lo(_environ)], ENVP
-
- /* Call `_init', which is the entry point to our own `.init'
- section; and register with `atexit' to have `exit' call
- `_fini', which is the entry point to our own `.fini' section. */
- call _init
- sethi %hi(_fini), TMP /* In delay slot of call. */
- or TMP, %lo(_fini), %o0 /* Argument to atexit is &_fini. */
- call atexit
- nop
-
- /* Call the user's main function, and exit with its value. */
- mov ARGC, %o0
- mov ARGV, %o1
- call main
- mov ENVP, %o2
-
- call exit /* This should never return. */
- unimp 0 /* Crash if somehow it does return. */
-
-/* Define a symbol for the first piece of initialized data. */
- .data
- .global __data_start
-__data_start:
- .long 0
- .weak data_start
- data_start = __data_start
diff --git a/sysdeps/sparc/memcopy.h b/sysdeps/sparc/memcopy.h
deleted file mode 100644
index 3fd4f3dfbc..0000000000
--- a/sysdeps/sparc/memcopy.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright (C) 1991 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., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include <sysdeps/generic/memcopy.h>
-#undef reg_char
-#define reg_char int
diff --git a/sysdeps/sparc/setjmp.S b/sysdeps/sparc/setjmp.S
deleted file mode 100644
index db8a3c2916..0000000000
--- a/sysdeps/sparc/setjmp.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 1991, 1993, 1994, 1996 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., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include <sysdep.h>
-
-#define _ASM 1
-#include <jmp_buf.h>
-
-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. */
- sethi %hi(C_SYMBOL_NAME (__sigjmp_save)), %g1
- st %sp, [%o0 + (JB_SP*4)]
- or %lo(C_SYMBOL_NAME (__sigjmp_save)), %g1, %g1
- st %fp, [%o0 + (JB_FP*4)]
- jmp %g1
- st %o7, [%o0 + (JB_PC*4)]
diff --git a/sysdeps/sparc/sparc32/Dist b/sysdeps/sparc/sparc32/Dist
new file mode 100644
index 0000000000..8bd3729740
--- /dev/null
+++ b/sysdeps/sparc/sparc32/Dist
@@ -0,0 +1,3 @@
+dotmul.S umul.S
+divrem.m4 sdiv.S udiv.S rem.S urem.S
+alloca.S
diff --git a/sysdeps/sparc/sparc32/Implies b/sysdeps/sparc/sparc32/Implies
new file mode 100644
index 0000000000..39a34c5f57
--- /dev/null
+++ b/sysdeps/sparc/sparc32/Implies
@@ -0,0 +1 @@
+wordsize-32
diff --git a/sysdeps/sparc/sparc32/Makefile b/sysdeps/sparc/sparc32/Makefile
new file mode 100644
index 0000000000..c7c867ef22
--- /dev/null
+++ b/sysdeps/sparc/sparc32/Makefile
@@ -0,0 +1,51 @@
+# Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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.
+
+ifeq ($(subdir),gnulib)
+routines = dotmul umul $(divrem) alloca
+endif # gnulib
+
+# We distribute these files, even though they are generated,
+# so as to avoid the need for a functioning m4 to build the library.
+divrem := sdiv udiv rem urem
+
++divrem-NAME-sdiv := div
++divrem-NAME-udiv := udiv
++divrem-NAME-rem := rem
++divrem-NAME-urem := urem
++divrem-NAME = $(+divrem-NAME-$(basename $(notdir $@)))
++divrem-OP-div := div
++divrem-OP-udiv := div
++divrem-OP-rem := rem
++divrem-OP-urem := rem
++divrem-S-div := true
++divrem-S-rem := true
++divrem-S-udiv := false
++divrem-S-urem := false
+$(divrem:%=$(sysdep_dir)/sparc/sparc32/%.S): $(sysdep_dir)/sparc/sparc32/divrem.m4
+ (echo "define(NAME,\`.$(+divrem-NAME)')\
+ define(OP,\`$(+divrem-OP-$(+divrem-NAME))')\
+ define(S,\`$(+divrem-S-$(+divrem-NAME))')\
+ /* This file is generated from divrem.m4; DO NOT EDIT! */"; \
+ cat $<) | $(M4) > $@-tmp
+# Make it unwritable so noone will edit it by mistake.
+ -chmod a-w $@-tmp
+ mv -f $@-tmp $@
+ test ! -d CVS || cvs commit -m'Regenerated from $<' $@
+
+sysdep-realclean := $(sysdep-realclean) $(divrem:%=sysdeps/sparc/sparc32/%.S)
diff --git a/sysdeps/sparc/sparc32/__longjmp.S b/sysdeps/sparc/sparc32/__longjmp.S
new file mode 100644
index 0000000000..1a74acc2cc
--- /dev/null
+++ b/sysdeps/sparc/sparc32/__longjmp.S
@@ -0,0 +1,64 @@
+/* Copyright (C) 1991, 1993, 1996, 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>
+
+#define _ASM 1
+#include <jmp_buf.h>
+#define ENV(reg) [%g1 + (reg * 4)]
+
+ENTRY(__longjmp)
+ /* Store our arguments in global registers so we can still
+ use them while unwinding frames and their register windows. */
+ mov %o0, %g1 /* ENV in %g1 */
+ orcc %o1, %g0, %g2 /* VAL in %g2 */
+ be,a 0f /* Branch if zero; else skip delay slot. */
+ mov 1, %g2 /* Delay slot only hit if zero: VAL = 1. */
+0:
+ /* Cache target FP in register %g3. */
+ ld ENV(JB_FP), %g3
+
+ /* Now we will loop, unwinding the register windows up the stack
+ until the restored %fp value matches the target value in %g3. */
+
+LOC(loop):
+ cmp %fp, %g3 /* Have we reached the target frame? */
+ bl,a LOC(loop) /* Loop while current fp is below target. */
+ restore /* Unwind register window in delay slot. */
+ be,a LOC(found) /* Better have hit it exactly. */
+ ld ENV(JB_SP), %o0 /* Delay slot: extract target SP. */
+
+LOC(bogus):
+ /* Get here only if the jmp_buf or stack is clobbered. */
+ call C_SYMBOL_NAME(abort)
+ nop
+ unimp 0
+
+LOC(found):
+ /* We have unwound register windows so %fp matches the target. */
+ cmp %o0, %sp /* Check jmp_buf SP vs register window. */
+ bge,a LOC(sp_ok) /* Saved must not be deeper than register. */
+ mov %o0, %sp /* OK, install new SP. */
+ b,a LOC(bogus) /* Bogus, we lose. */
+
+LOC(sp_ok):
+ ld ENV(JB_PC), %o0 /* Extract target return PC. */
+ jmp %o0 + 8 /* Return there. */
+ mov %g2, %o0 /* Delay slot: set return value. */
+
+END(__longjmp)
diff --git a/sysdeps/sparc/sparc32/abort-instr.h b/sysdeps/sparc/sparc32/abort-instr.h
new file mode 100644
index 0000000000..bd5c472d4a
--- /dev/null
+++ b/sysdeps/sparc/sparc32/abort-instr.h
@@ -0,0 +1,2 @@
+/* An instruction which should crash any program. */
+#define ABORT_INSTRUCTION asm ("unimp")
diff --git a/sysdeps/sparc/sparc32/add_n.S b/sysdeps/sparc/sparc32/add_n.S
new file mode 100644
index 0000000000..5a6fccbbee
--- /dev/null
+++ b/sysdeps/sparc/sparc32/add_n.S
@@ -0,0 +1,238 @@
+! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+! sum in a third limb vector.
+!
+! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+#define RES_PTR %o0
+#define S1_PTR %o1
+#define S2_PTR %o2
+#define SIZE %o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_add_n)
+ xor S2_PTR,RES_PTR,%g1
+ andcc %g1,4,%g0
+ bne LOC(1) ! branch if alignment differs
+ nop
+! ** V1a **
+LOC(0): andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
+ be LOC(v1) ! if no, branch
+ nop
+/* Add least significant limb separately to align RES_PTR and S2_PTR */
+ ld [S1_PTR],%g4
+ add S1_PTR,4,S1_PTR
+ ld [S2_PTR],%g2
+ add S2_PTR,4,S2_PTR
+ add SIZE,-1,SIZE
+ addcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+LOC(v1):
+ addx %g0,%g0,%o4 ! save cy in register
+ cmp SIZE,2 ! if SIZE < 2 ...
+ bl LOC(end2) ! ... branch to tail code
+ subcc %g0,%o4,%g0 ! restore cy
+
+ ld [S1_PTR+0],%g4
+ addcc SIZE,-10,SIZE
+ ld [S1_PTR+4],%g1
+ ldd [S2_PTR+0],%g2
+ blt LOC(fin1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop1):
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+12],%g1
+ ldd [S2_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+16],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+20],%g1
+ ldd [S2_PTR+16],%g2
+ std %o4,[RES_PTR+8]
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+24],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+28],%g1
+ ldd [S2_PTR+24],%g2
+ std %o4,[RES_PTR+16]
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+32],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+36],%g1
+ ldd [S2_PTR+32],%g2
+ std %o4,[RES_PTR+24]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop1)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin1):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+LOC(loope1):
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+12],%g1
+ ldd [S2_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope1)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end1):
+ addxcc %g4,%g2,%o4
+ addxcc %g1,%g3,%o5
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+
+ andcc SIZE,1,%g0
+ be LOC(ret1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+ ld [S1_PTR+8],%g4
+ ld [S2_PTR+8],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[RES_PTR+8]
+
+LOC(ret1):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+LOC(1): xor S1_PTR,RES_PTR,%g1
+ andcc %g1,4,%g0
+ bne LOC(2)
+ nop
+! ** V1b **
+ mov S2_PTR,%g1
+ mov S1_PTR,S2_PTR
+ b LOC(0)
+ mov %g1,S1_PTR
+
+! ** V2 **
+/* If we come here, the alignment of S1_PTR and RES_PTR as well as the
+ alignment of S2_PTR and RES_PTR differ. Since there are only two ways
+ things can be aligned (that we care about) we now know that the alignment
+ of S1_PTR and S2_PTR are the same. */
+
+LOC(2): cmp SIZE,1
+ be LOC(jone)
+ nop
+ andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
+ be LOC(v2) ! if no, branch
+ nop
+/* Add least significant limb separately to align S1_PTR and S2_PTR */
+ ld [S1_PTR],%g4
+ add S1_PTR,4,S1_PTR
+ ld [S2_PTR],%g2
+ add S2_PTR,4,S2_PTR
+ add SIZE,-1,SIZE
+ addcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+
+LOC(v2):
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ blt LOC(fin2)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop2):
+ ldd [S1_PTR+0],%g2
+ ldd [S2_PTR+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+4]
+ ldd [S1_PTR+8],%g2
+ ldd [S2_PTR+8],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+8]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+12]
+ ldd [S1_PTR+16],%g2
+ ldd [S2_PTR+16],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+16]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+20]
+ ldd [S1_PTR+24],%g2
+ ldd [S2_PTR+24],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+24]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+28]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop2)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin2):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end2)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(loope2):
+ ldd [S1_PTR+0],%g2
+ ldd [S2_PTR+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+4]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope2)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end2):
+ andcc SIZE,1,%g0
+ be LOC(ret2)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+LOC(jone):
+ ld [S1_PTR],%g4
+ ld [S2_PTR],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+
+LOC(ret2):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+END(__mpn_add_n)
diff --git a/sysdeps/sparc/addmul_1.S b/sysdeps/sparc/sparc32/addmul_1.S
index 375d25db6b..5e0c381f4f 100644
--- a/sysdeps/sparc/addmul_1.S
+++ b/sysdeps/sparc/sparc32/addmul_1.S
@@ -1,20 +1,20 @@
! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add
! the result to a second limb vector.
-
-! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
-
+!
+! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+!
! This file is part of the GNU MP Library.
-
+!
! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
-
+!
! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details.
-
+!
! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -22,17 +22,14 @@
! INPUT PARAMETERS
-! res_ptr o0
-! s1_ptr o1
-! size o2
-! s2_limb o3
+! RES_PTR o0
+! S1_PTR o1
+! SIZE o2
+! S2_LIMB o3
-#include "sysdep.h"
+#include <sysdep.h>
-.text
- .align 4
- .global C_SYMBOL_NAME(__mpn_addmul_1)
-C_SYMBOL_NAME(__mpn_addmul_1):
+ENTRY(__mpn_addmul_1)
! Make S1_PTR and RES_PTR point at the end of their blocks
! and put (- 4 x SIZE) in index/loop counter.
sll %o2,2,%o2
@@ -41,19 +38,19 @@ C_SYMBOL_NAME(__mpn_addmul_1):
sub %g0,%o2,%o2
cmp %o3,0xfff
- bgu Large
+ bgu LOC(large)
nop
ld [%o1+%o2],%o5
mov 0,%o0
- b L0
+ b LOC(0)
add %o4,-4,%o4
-Loop0:
+LOC(loop0):
addcc %o5,%g1,%g1
ld [%o1+%o2],%o5
addx %o0,%g0,%o0
st %g1,[%o4+%o2]
-L0: wr %g0,%o3,%y
+LOC(0): wr %g0,%o3,%y
sra %o5,31,%g2
and %o3,%g2,%g2
andcc %g1,0,%g1
@@ -79,7 +76,7 @@ L0: wr %g0,%o3,%y
addcc %g1,%o0,%g1
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter
- bne Loop0
+ bne LOC(loop0)
ld [%o4+%o2],%o5
addcc %o5,%g1,%g1
@@ -88,17 +85,18 @@ L0: wr %g0,%o3,%y
st %g1,[%o4+%o2]
-Large: ld [%o1+%o2],%o5
+LOC(large):
+ ld [%o1+%o2],%o5
mov 0,%o0
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
- b L1
+ b LOC(1)
add %o4,-4,%o4
-Loop:
+LOC(loop):
addcc %o5,%g3,%g3
ld [%o1+%o2],%o5
addx %o0,%g0,%o0
st %g3,[%o4+%o2]
-L1: wr %g0,%o5,%y
+LOC(1): wr %g0,%o5,%y
and %o5,%g4,%g2
andcc %g0,%g0,%g1
mulscc %g1,%o3,%g1
@@ -138,10 +136,12 @@ L1: wr %g0,%o5,%y
addcc %g3,%o0,%g3
addx %g2,%g1,%o0
addcc %o2,4,%o2
- bne Loop
+ bne LOC(loop)
ld [%o4+%o2],%o5
addcc %o5,%g3,%g3
addx %o0,%g0,%o0
retl
st %g3,[%o4+%o2]
+
+END(__mpn_addmul_1)
diff --git a/sysdeps/sparc/sparc32/alloca.S b/sysdeps/sparc/sparc32/alloca.S
new file mode 100644
index 0000000000..1eb755afab
--- /dev/null
+++ b/sysdeps/sparc/sparc32/alloca.S
@@ -0,0 +1,33 @@
+/* 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>
+
+/* Code produced by Sun's C compiler calls this function with two extra
+ arguments which it makes relocatable symbols but seem always to be
+ the constant 96; I have no idea what they are for. */
+
+#ifndef NO_UNDERSCORES
+#define __builtin_alloca ___builtin_alloca
+#endif
+
+ENTRY (__builtin_alloca)
+ sub %sp, %o0, %sp /* Push some stack space. */
+ retl /* Return; the returned buffer leaves 96 */
+ add %sp, 96, %o0 /* bytes of register save area at the top. */
+END (__builtin_alloca)
diff --git a/sysdeps/sparc/sparc32/bsd-_setjmp.S b/sysdeps/sparc/sparc32/bsd-_setjmp.S
new file mode 100644
index 0000000000..4e6a2da560
--- /dev/null
+++ b/sysdeps/sparc/sparc32/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* _setjmp is in setjmp.S */
diff --git a/sysdeps/sparc/sparc32/bsd-setjmp.S b/sysdeps/sparc/sparc32/bsd-setjmp.S
new file mode 100644
index 0000000000..1da848d2f1
--- /dev/null
+++ b/sysdeps/sparc/sparc32/bsd-setjmp.S
@@ -0,0 +1 @@
+/* setjmp is in setjmp.S */
diff --git a/sysdeps/sparc/bytesex.h b/sysdeps/sparc/sparc32/bytesex.h
index f1a75c0652..f1a75c0652 100644
--- a/sysdeps/sparc/bytesex.h
+++ b/sysdeps/sparc/sparc32/bytesex.h
diff --git a/sysdeps/sparc/divrem.m4 b/sysdeps/sparc/sparc32/divrem.m4
index bde8a21e29..30d532ad77 100644
--- a/sysdeps/sparc/divrem.m4
+++ b/sysdeps/sparc/sparc32/divrem.m4
@@ -47,8 +47,8 @@ define(V, `%o5')dnl
dnl
dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d
define(T, `%g1')dnl
-define(SC, `%g7')dnl
-ifelse(S, `true', `define(SIGN, `%g6')')dnl
+define(SC, `%g2')dnl
+ifelse(S, `true', `define(SIGN, `%g3')')dnl
dnl
dnl This is the recursive definition for developing quotient digits.
@@ -65,7 +65,7 @@ dnl modified to reflect the output R.
dnl
define(DEVELOP_QUOTIENT_BITS,
` ! depth $1, accumulated bits $2
- bl L.$1.eval(2**N+$2)
+ bl LOC($1.eval(2**N+$2))
srl V,1,V
! remainder is positive
subcc R,V,R
@@ -73,7 +73,7 @@ define(DEVELOP_QUOTIENT_BITS,
` b 9f
add Q, ($2*2+1), Q
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')')
-L.$1.eval(2**N+$2):
+LOC($1.eval(2**N+$2)):
! remainder is negative
addcc R,V,R
ifelse($1, N,
@@ -82,14 +82,10 @@ L.$1.eval(2**N+$2):
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')')
ifelse($1, 1, `9:')')dnl
-#include "DEFS.h"
-#ifdef __svr4__
+#include <sysdep.h>
#include <sys/trap.h>
-#else
-#include <machine/trap.h>
-#endif
-FUNC(NAME)
+ENTRY(NAME)
ifelse(S, `true',
` ! compute sign of result; if neither is negative, no problem
orcc divisor, dividend, %g0 ! either negative?
@@ -120,11 +116,11 @@ ifelse(OP, `div',
1:
cmp R, V ! if divisor exceeds dividend, done
- blu Lgot_result ! (and algorithm fails otherwise)
+ blu LOC(got_result) ! (and algorithm fails otherwise)
clr Q
sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T
cmp R, T
- blu Lnot_really_big
+ blu LOC(not_really_big)
clr ITER
! `Here the dividend is >= 2**(31-N) or so. We must be careful here,
@@ -142,7 +138,7 @@ ifelse(OP, `div',
! Now compute SC.
2: addcc V, V, V
- bcc Lnot_too_big
+ bcc LOC(not_too_big)
add SC, 1, SC
! We get here if the divisor overflowed while shifting.
@@ -151,14 +147,14 @@ ifelse(OP, `div',
sll T, TOPBITS, T ! high order bit
srl V, 1, V ! rest of V
add V, T, V
- b Ldo_single_div
+ b LOC(do_single_div)
sub SC, 1, SC
- Lnot_too_big:
+ LOC(not_too_big):
3: cmp V, R
blu 2b
nop
- be Ldo_single_div
+ be LOC(do_single_div)
nop
/* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */
@@ -173,15 +169,15 @@ ifelse(OP, `div',
! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around.
! So we unroll slightly...
- Ldo_single_div:
+ LOC(do_single_div):
subcc SC, 1, SC
- bl Lend_regular_divide
+ bl LOC(end_regular_divide)
nop
sub R, V, R
mov 1, Q
- b Lend_single_divloop
+ b LOC(end_single_divloop)
nop
- Lsingle_divloop:
+ LOC(single_divloop):
sll Q, 1, Q
bl 1f
srl V, 1, V
@@ -193,37 +189,37 @@ ifelse(OP, `div',
add R, V, R
sub Q, 1, Q
2:
- Lend_single_divloop:
+ LOC(end_single_divloop):
subcc SC, 1, SC
- bge Lsingle_divloop
+ bge LOC(single_divloop)
tst R
- b,a Lend_regular_divide
+ b,a LOC(end_regular_divide)
-Lnot_really_big:
+LOC(not_really_big):
1:
sll V, N, V
cmp V, R
bleu 1b
addcc ITER, 1, ITER
- be Lgot_result
+ be LOC(got_result)
sub ITER, 1, ITER
tst R ! set up for initial iteration
-Ldivloop:
+LOC(divloop):
sll Q, N, Q
DEVELOP_QUOTIENT_BITS(1, 0)
-Lend_regular_divide:
+LOC(end_regular_divide):
subcc ITER, 1, ITER
- bge Ldivloop
+ bge LOC(divloop)
tst R
- bl,a Lgot_result
+ bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!)
ifelse(OP, `div',
` sub Q, 1, Q
', ` add R, divisor, R
')
-Lgot_result:
+LOC(got_result):
ifelse(S, `true',
` ! check to see if answer should be < 0
tst SIGN
@@ -232,3 +228,5 @@ ifelse(S, `true',
1:')
retl
ifelse(OP, `div', `mov Q, %o0', `mov R, %o0')
+
+END(NAME)
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
new file mode 100644
index 0000000000..ef041e2e11
--- /dev/null
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -0,0 +1,398 @@
+/* Machine-dependent ELF dynamic relocation inline functions. SPARC version.
+ Copyright (C) 1996, 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. */
+
+#define ELF_MACHINE_NAME "sparc"
+
+#include <assert.h>
+#include <string.h>
+#include <link.h>
+#include <sys/param.h>
+
+
+/* Some SPARC opcodes we need to use for self-modifying code. */
+#define OPCODE_NOP 0x01000000 /* nop */
+#define OPCODE_CALL 0x40000000 /* call ?; add PC-rel word address */
+#define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */
+#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
+#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
+
+#define LD_SO_PRELOAD ((_dl_hwcap & HWCAP_SPARC_V9) ? "/etc/ld.so.preload32" : "/etc/ld.so.preload")
+
+/* Return nonzero iff E_MACHINE is compatible with the running host. */
+static inline int
+elf_machine_matches_host (Elf32_Half e_machine)
+{
+ extern unsigned long _dl_hwcap;
+ unsigned long *hwcap;
+ weak_extern(_dl_hwcap);
+
+ if (e_machine == EM_SPARC) return 1;
+ if (e_machine != EM_SPARC32PLUS) return 0;
+ hwcap = &_dl_hwcap;
+ __asm ("" : "=r" (hwcap) : "0" (hwcap));
+ return (hwcap && (*hwcap & HWCAP_SPARC_V9));
+}
+
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+static inline Elf32_Addr
+elf_machine_dynamic (void)
+{
+ register Elf32_Addr *got asm ("%l7");
+ return *got;
+}
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr
+elf_machine_load_address (void)
+{
+ register Elf32_Addr pc __asm("%o7"), pic __asm("%l7"), got;
+
+ /* Utilize the fact that a local .got entry will be partially
+ initialized at startup awaiting its RELATIVE fixup. */
+
+ __asm("sethi %%hi(.Load_address),%1\n"
+ ".Load_address:\n\t"
+ "call 1f\n\t"
+ "or %1,%%lo(.Load_address),%1\n"
+ "1:\tld [%2+%1],%1"
+ : "=r"(pc), "=r"(got) : "r"(pic));
+
+ return pc - got;
+}
+
+/* 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)
+{
+ 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_SP;
+ /* Construct PC-relative word address. */
+ plt[1] = OPCODE_CALL | (((Elf32_Addr) &_dl_runtime_resolve -
+ (Elf32_Addr) &plt[1]) >> 2);
+ plt[2] = OPCODE_NOP; /* Fill call delay slot. */
+ plt[3] = (Elf32_Addr) l;
+ }
+
+ return lazy;
+}
+
+/* This code is used in dl-runtime.c to call the `fixup' function
+ and then redirect to the address it returns. */
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve, @function
+_dl_runtime_resolve:
+ /* Set up the arguments to fixup --
+ %o0 = link_map out of plt0
+ %o1 = offset of reloc entry */
+ ld [%o7 + 8], %o0
+ srl %g1, 10, %o1
+ call fixup
+ sub %o1, 4*12, %o1
+ jmp %o0
+ restore
+ .size _dl_runtime_resolve, . - _dl_runtime_resolve");
+
+/* 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)
+
+/* The PLT uses Elf32_Rela relocs. */
+#define elf_machine_relplt elf_machine_rela
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT 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
+
+/* 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
+.previous");
+
+/* Return the final value of a plt relocation. */
+static inline Elf32_Addr
+elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr value)
+{
+ return value + reloc->r_addend;
+}
+
+static inline void
+elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+#ifndef RTLD_BOOTSTRAP
+ extern unsigned long _dl_hwcap;
+ unsigned long *hwcap;
+ int do_flush;
+ weak_extern(_dl_hwcap);
+
+ hwcap = &_dl_hwcap;
+ /* Make sure gcc is not clever too much to optimize this,
+ so that _dl_hwcap is dereferenced even if it should not.
+ Normally, we flush, just if we know we don't have to,
+ we try to avoid that. Kernel should emulate flush
+ if we execute it and hw does not support it. */
+ __asm ("" : "=r" (hwcap) : "0" (hwcap));
+ do_flush = (!hwcap || (*hwcap & HWCAP_SPARC_FLUSH));
+#endif
+
+ /* For thread safety, write the instructions from the bottom and
+ flush before we overwrite the critical "b,a". This of course
+ need not be done during bootstrapping, since there are no threads.
+ But we also can't tell if we _can_ use flush, so don't. */
+
+ reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
+#ifndef RTLD_BOOTSTRAP
+ if (do_flush)
+ __asm __volatile ("flush %0+8" : : "r"(reloc_addr));
+#endif
+
+ reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
+#ifndef RTLD_BOOTSTRAP
+ if (do_flush)
+ __asm __volatile ("flush %0+4" : : "r"(reloc_addr));
+#endif
+}
+
+#ifdef RESOLVE
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+static inline void
+elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+ const Elf32_Sym *sym)
+{
+ Elf32_Addr * const reloc_addr = (void *) (map->l_addr + reloc->r_offset);
+
+#ifndef RTLD_BOOTSTRAP
+ /* This is defined in rtld.c, but nowhere in the static libc.a; make the
+ reference weak so static programs can still link. This declaration
+ cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
+ because rtld.c contains the common defn for _dl_rtld_map, which is
+ incompatible with a weak decl in the same file. */
+ weak_extern (_dl_rtld_map);
+#endif
+
+ if (ELF32_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE)
+ {
+#ifndef RTLD_BOOTSTRAP
+ if (map != &_dl_rtld_map) /* Already done in rtld itself. */
+#endif
+ *reloc_addr += map->l_addr + reloc->r_addend;
+ }
+ else
+ {
+ const int r_type = ELF32_R_TYPE (reloc->r_info);
+ Elf32_Addr value;
+
+ value = RESOLVE (&sym, (r_type == R_SPARC_COPY ? DL_LOOKUP_NOEXEC
+ : r_type == R_SPARC_JMP_SLOT ? DL_LOOKUP_NOPLT
+ : 0));
+ if (sym)
+ value += sym->st_value;
+ value += reloc->r_addend; /* Assume copy relocs have zero addend. */
+
+ switch (r_type)
+ {
+ case R_SPARC_COPY:
+#ifndef RTLD_BOOTSTRAP
+ memcpy (reloc_addr, (void *) value, sym->st_size);
+#endif
+ break;
+ case R_SPARC_GLOB_DAT:
+ case R_SPARC_32:
+ *reloc_addr = value;
+ break;
+ case R_SPARC_JMP_SLOT:
+ elf_machine_fixup_plt(map, reloc, reloc_addr, value);
+ break;
+ case R_SPARC_8:
+ *(char *) reloc_addr = value;
+ break;
+ case R_SPARC_16:
+ *(short *) reloc_addr = value;
+ break;
+ case R_SPARC_DISP8:
+ *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
+ break;
+ case R_SPARC_DISP16:
+ *(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
+ break;
+ case R_SPARC_DISP32:
+ *reloc_addr = (value - (Elf32_Addr) reloc_addr);
+ break;
+ case R_SPARC_LO10:
+ *reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff);
+ break;
+ case R_SPARC_WDISP30:
+ *reloc_addr = ((*reloc_addr & 0xc0000000)
+ | ((value - (unsigned int) reloc_addr) >> 2));
+ break;
+ case R_SPARC_HI22:
+ *reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10);
+ break;
+ case R_SPARC_NONE: /* Alright, Wilbur. */
+ break;
+ default:
+ assert (! "unexpected dynamic reloc type");
+ break;
+ }
+ }
+}
+
+static inline void
+elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
+{
+ switch (ELF32_R_TYPE (reloc->r_info))
+ {
+ case R_SPARC_NONE:
+ case R_SPARC_JMP_SLOT:
+ break;
+ default:
+ assert (! "unexpected PLT reloc type");
+ break;
+ }
+}
+
+#endif /* RESOLVE */
diff --git a/sysdeps/sparc/dotmul.S b/sysdeps/sparc/sparc32/dotmul.S
index 1c59a27e80..821aa8bdb4 100644
--- a/sysdeps/sparc/dotmul.S
+++ b/sysdeps/sparc/sparc32/dotmul.S
@@ -10,11 +10,13 @@
* This code optimizes short (less than 13-bit) multiplies.
*/
-#include "DEFS.h"
-FUNC(.mul)
+#include <sysdep.h>
+
+
+ENTRY(.mul)
mov %o0, %y ! multiplier -> Y
andncc %o0, 0xfff, %g0 ! test bits 12..31
- be Lmul_shortway ! if zero, can do it the short way
+ be LOC(mul_shortway) ! if zero, can do it the short way
andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
/*
@@ -81,7 +83,7 @@ FUNC(.mul)
! and put upper half in place
#endif
-Lmul_shortway:
+LOC(mul_shortway):
/*
* Short multiply. 12 steps, followed by a final shift step.
* The resulting bits are off by 12 and (32-12) = 20 bit positions,
@@ -121,3 +123,5 @@ Lmul_shortway:
or %o5, %o0, %o0 ! construct low part of result
retl
sra %o4, 20, %o1 ! ... and extract high part of result
+
+END(.mul)
diff --git a/sysdeps/sparc/sparc32/elf/Makefile b/sysdeps/sparc/sparc32/elf/Makefile
new file mode 100644
index 0000000000..319fbdef10
--- /dev/null
+++ b/sysdeps/sparc/sparc32/elf/Makefile
@@ -0,0 +1,4 @@
+# Sparc/ELF specific definitions.
+
+# The assembler on SPARC needs the -fPIC flag even when it's assembler code.
+ASFLAGS-.so = -fPIC
diff --git a/sysdeps/sparc/sparc32/elf/start.S b/sysdeps/sparc/sparc32/elf/start.S
new file mode 100644
index 0000000000..24715e68be
--- /dev/null
+++ b/sysdeps/sparc/sparc32/elf/start.S
@@ -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, 2, %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
diff --git a/sysdeps/sparc/fpu_control.h b/sysdeps/sparc/sparc32/fpu/fpu_control.h
index a8015abc29..c069318970 100644
--- a/sysdeps/sparc/fpu_control.h
+++ b/sysdeps/sparc/sparc32/fpu/fpu_control.h
@@ -31,47 +31,28 @@
#define _FPU_SINGLE 0x10000000 /* DO NOT USE */
/* rounding control / Sparc */
-#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
-#define _FPU_RC_DOWN 0x80000000
-#define _FPU_RC_UP 0xc0000000
+#define _FPU_RC_DOWN 0xc0000000
+#define _FPU_RC_UP 0x80000000
#define _FPU_RC_ZERO 0x40000000
+#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
-#define _FPU_RESERVED 0x300000 /* Reserved bits in cw */
+#define _FPU_RESERVED 0x30300000 /* Reserved bits in cw */
/* Now two recommended cw */
-/* Linux default:
+/* Linux and IEEE default:
- extended precision
- rounding to nearest
- - exceptions on overflow, zero divide and NaN */
-#define _FPU_DEFAULT 0x1f
-
-/* IEEE: same as above, but exceptions */
+ - no exceptions. */
+#define _FPU_DEFAULT 0x0
#define _FPU_IEEE 0x0
-/* private namespace. It should only be used by crt0.o. */
-extern unsigned short __fpu_control;
-
-__BEGIN_DECLS
-
-/* called by crt0.o. It can be used to manipulate 387 control word. */
-extern void __setfpucw __P ((unsigned short));
-
-__END_DECLS
-
/* Type of the control word. */
-typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
+typedef unsigned int fpu_control_t;
#define _FPU_GETCW(cw) __asm__ ("st %%fsr,%0" : "=m" (*&cw))
-#define _FPU_SETCW(cw) __asm__ ("ld %0,%%fsr" : "=m" (*&cw))
-
-#if 0
-/* The intel original macros */
-/* Macros for accessing the hardware control word. */
-#define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
-#define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
-#endif
+#define _FPU_SETCW(cw) __asm__ ("ld %0,%%fsr" : : "m" (*&cw))
/* Default control word set at startup. */
extern fpu_control_t __fpu_control;
diff --git a/sysdeps/sparc/jmp_buf.h b/sysdeps/sparc/sparc32/jmp_buf.h
index 43bae1a496..fe8f11e8b5 100644
--- a/sysdeps/sparc/jmp_buf.h
+++ b/sysdeps/sparc/sparc32/jmp_buf.h
@@ -1,9 +1,9 @@
/* Define the machine-dependent type `jmp_buf'. SPARC version. */
-#if defined (__USE_MISC) || defined (_ASM)
-#define JB_SP 0
-#define JB_FP 1
-#define JB_PC 2
+#if defined __USE_MISC || defined _ASM
+# define JB_SP 0
+# define JB_FP 1
+# define JB_PC 2
#endif
#ifndef _ASM
diff --git a/sysdeps/sparc/lshift.S b/sysdeps/sparc/sparc32/lshift.S
index 4f0595f2fb..35aa9378b3 100644
--- a/sysdeps/sparc/lshift.S
+++ b/sysdeps/sparc/sparc32/lshift.S
@@ -1,19 +1,19 @@
-! sparc __mpn_lshift --
-
-! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
+! Sparc __mpn_lshift --
+!
+! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+!
! This file is part of the GNU MP Library.
-
+!
! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
-
+!
! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details.
-
+!
! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -21,17 +21,14 @@
! INPUT PARAMETERS
-! res_ptr %o0
-! src_ptr %o1
-! size %o2
-! cnt %o3
+! RES_PTR %o0
+! SRC_PTR %o1
+! SIZE %o2
+! CNT %o3
-#include "sysdep.h"
+#include <sysdep.h>
- .text
- .align 4
- .global C_SYMBOL_NAME(__mpn_lshift)
-C_SYMBOL_NAME(__mpn_lshift):
+ENTRY(__mpn_lshift)
sll %o2,2,%g1
add %o1,%g1,%o1 ! make %o1 point at end of src
ld [%o1-4],%g2 ! load first limb
@@ -40,12 +37,13 @@ C_SYMBOL_NAME(__mpn_lshift):
add %o2,-1,%o2
andcc %o2,4-1,%g4 ! number of limbs in first loop
srl %g2,%o5,%g1 ! compute function result
- be L0 ! if multiple of 4 limbs, skip first loop
+ be LOC(0) ! if multiple of 4 limbs, skip first loop
st %g1,[%sp+80]
sub %o2,%g4,%o2 ! adjust count for main loop
-Loop0: ld [%o1-8],%g3
+LOC(loop0):
+ ld [%o1-8],%g3
add %o0,-4,%o0
add %o1,-4,%o1
addcc %g4,-1,%g4
@@ -53,14 +51,15 @@ Loop0: ld [%o1-8],%g3
srl %g3,%o5,%g1
mov %g3,%g2
or %o4,%g1,%o4
- bne Loop0
+ bne LOC(loop0)
st %o4,[%o0+0]
-L0: tst %o2
- be Lend
+LOC(0): tst %o2
+ be LOC(end)
nop
-Loop: ld [%o1-8],%g3
+LOC(loop):
+ ld [%o1-8],%g3
add %o0,-16,%o0
addcc %o2,-4,%o2
sll %g2,%o3,%o4
@@ -86,10 +85,13 @@ Loop: ld [%o1-8],%g3
add %o1,-16,%o1
or %g4,%g1,%g4
- bne Loop
+ bne LOC(loop)
st %g4,[%o0+0]
-Lend: sll %g2,%o3,%g2
+LOC(end):
+ sll %g2,%o3,%g2
st %g2,[%o0-4]
retl
ld [%sp+80],%o0
+
+END(__mpn_lshift)
diff --git a/sysdeps/sparc/sparc32/memcopy.h b/sysdeps/sparc/sparc32/memcopy.h
new file mode 100644
index 0000000000..ff73f453da
--- /dev/null
+++ b/sysdeps/sparc/sparc32/memcopy.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 1991, 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 <sysdeps/generic/memcopy.h>
+#undef reg_char
+#define reg_char int
diff --git a/sysdeps/sparc/mul_1.S b/sysdeps/sparc/sparc32/mul_1.S
index 142fd8ba2a..d39ec61028 100644
--- a/sysdeps/sparc/mul_1.S
+++ b/sysdeps/sparc/sparc32/mul_1.S
@@ -1,20 +1,20 @@
! SPARC __mpn_mul_1 -- Multiply a limb vector with a limb and store
! the result in a second limb vector.
-
-! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
-
+!
+! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+!
! This file is part of the GNU MP Library.
-
+!
! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
-
+!
! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details.
-
+!
! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -22,10 +22,10 @@
! INPUT PARAMETERS
-! res_ptr o0
-! s1_ptr o1
-! size o2
-! s2_limb o3
+! RES_PTR o0
+! S1_PTR o1
+! SIZE o2
+! S2_LIMB o3
! ADD CODE FOR SMALL MULTIPLIERS!
!1: ld
@@ -89,12 +89,9 @@
! sll a,29,y2
! st x,
-#include "sysdep.h"
+#include <sysdep.h>
-.text
- .align 4
- .global C_SYMBOL_NAME(__mpn_mul_1)
-C_SYMBOL_NAME(__mpn_mul_1):
+ENTRY(__mpn_mul_1)
! Make S1_PTR and RES_PTR point at the end of their blocks
! and put (- 4 x SIZE) in index/loop counter.
sll %o2,2,%o2
@@ -103,16 +100,16 @@ C_SYMBOL_NAME(__mpn_mul_1):
sub %g0,%o2,%o2
cmp %o3,0xfff
- bgu Large
+ bgu LOC(large)
nop
ld [%o1+%o2],%o5
mov 0,%o0
- b L0
+ b LOC(0)
add %o4,-4,%o4
-Loop0:
+LOC(loop0):
st %g1,[%o4+%o2]
-L0: wr %g0,%o3,%y
+LOC(0): wr %g0,%o3,%y
sra %o5,31,%g2
and %o3,%g2,%g2
andcc %g1,0,%g1
@@ -138,21 +135,22 @@ L0: wr %g0,%o3,%y
addcc %g1,%o0,%g1
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter
- bne,a Loop0
+ bne,a LOC(loop0)
ld [%o1+%o2],%o5
retl
st %g1,[%o4+%o2]
-Large: ld [%o1+%o2],%o5
+LOC(large):
+ ld [%o1+%o2],%o5
mov 0,%o0
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
- b L1
+ b LOC(1)
add %o4,-4,%o4
-Loop:
+LOC(loop):
st %g3,[%o4+%o2]
-L1: wr %g0,%o5,%y
+LOC(1): wr %g0,%o5,%y
and %o5,%g4,%g2 ! g2 = S1_LIMB iff S2_LIMB < 0, else 0
andcc %g0,%g0,%g1
mulscc %g1,%o3,%g1
@@ -192,8 +190,10 @@ L1: wr %g0,%o5,%y
addcc %g3,%o0,%g3
addx %g2,%g1,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter
- bne,a Loop
+ bne,a LOC(loop)
ld [%o1+%o2],%o5
retl
st %g3,[%o4+%o2]
+
+END(__mpn_mul_1)
diff --git a/sysdeps/sparc/rem.S b/sysdeps/sparc/sparc32/rem.S
index 17662f7fd4..effacee0d0 100644
--- a/sysdeps/sparc/rem.S
+++ b/sysdeps/sparc/sparc32/rem.S
@@ -37,18 +37,14 @@
-#include "DEFS.h"
-#ifdef __svr4__
+#include <sysdep.h>
#include <sys/trap.h>
-#else
-#include <machine/trap.h>
-#endif
-FUNC(.rem)
+ENTRY(.rem)
! compute sign of result; if neither is negative, no problem
orcc %o1, %o0, %g0 ! either negative?
bge 2f ! no, go do the divide
- mov %o0, %g6 ! sign of remainder matches %o0
+ mov %o0, %g3 ! sign of remainder matches %o0
tst %o1
bge 1f
tst %o0
@@ -72,11 +68,11 @@ FUNC(.rem)
1:
cmp %o3, %o5 ! if %o1 exceeds %o0, done
- blu Lgot_result ! (and algorithm fails otherwise)
+ blu LOC(got_result) ! (and algorithm fails otherwise)
clr %o2
sethi %hi(1 << (32 - 4 - 1)), %g1
cmp %o3, %g1
- blu Lnot_really_big
+ blu LOC(not_really_big)
clr %o4
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
@@ -87,15 +83,15 @@ FUNC(.rem)
1:
cmp %o5, %g1
bgeu 3f
- mov 1, %g7
+ mov 1, %g2
sll %o5, 4, %o5
b 1b
add %o4, 1, %o4
- ! Now compute %g7.
+ ! Now compute %g2.
2: addcc %o5, %o5, %o5
- bcc Lnot_too_big
- add %g7, 1, %g7
+ bcc LOC(not_too_big)
+ add %g2, 1, %g2
! We get here if the %o1 overflowed while shifting.
! This means that %o3 has the high-order bit set.
@@ -103,20 +99,20 @@ FUNC(.rem)
sll %g1, 4, %g1 ! high order bit
srl %o5, 1, %o5 ! rest of %o5
add %o5, %g1, %o5
- b Ldo_single_div
- sub %g7, 1, %g7
+ b LOC(do_single_div)
+ sub %g2, 1, %g2
- Lnot_too_big:
+ LOC(not_too_big):
3: cmp %o5, %o3
blu 2b
nop
- be Ldo_single_div
+ be LOC(do_single_div)
nop
/* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */
! %o5 > %o3: went too far: back up 1 step
! srl %o5, 1, %o5
- ! dec %g7
+ ! dec %g2
! do single-bit divide steps
!
! We have to be careful here. We know that %o3 >= %o5, so we can do the
@@ -125,15 +121,15 @@ FUNC(.rem)
! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around.
! So we unroll slightly...
- Ldo_single_div:
- subcc %g7, 1, %g7
- bl Lend_regular_divide
+ LOC(do_single_div):
+ subcc %g2, 1, %g2
+ bl LOC(end_regular_divide)
nop
sub %o3, %o5, %o3
mov 1, %o2
- b Lend_single_divloop
+ b LOC(end_single_divloop)
nop
- Lsingle_divloop:
+ LOC(single_divloop):
sll %o2, 1, %o2
bl 1f
srl %o5, 1, %o5
@@ -145,66 +141,66 @@ FUNC(.rem)
add %o3, %o5, %o3
sub %o2, 1, %o2
2:
- Lend_single_divloop:
- subcc %g7, 1, %g7
- bge Lsingle_divloop
+ LOC(end_single_divloop):
+ subcc %g2, 1, %g2
+ bge LOC(single_divloop)
tst %o3
- b,a Lend_regular_divide
+ b,a LOC(end_regular_divide)
-Lnot_really_big:
+LOC(not_really_big):
1:
sll %o5, 4, %o5
cmp %o5, %o3
bleu 1b
addcc %o4, 1, %o4
- be Lgot_result
+ be LOC(got_result)
sub %o4, 1, %o4
tst %o3 ! set up for initial iteration
-Ldivloop:
+LOC(divloop):
sll %o2, 4, %o2
! depth 1, accumulated bits 0
- bl L.1.16
+ bl LOC(1.16)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 2, accumulated bits 1
- bl L.2.17
+ bl LOC(2.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits 3
- bl L.3.19
+ bl LOC(3.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 7
- bl L.4.23
+ bl LOC(4.23)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (7*2+1), %o2
-L.4.23:
+LOC(4.23):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (7*2-1), %o2
-L.3.19:
+LOC(3.19):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 5
- bl L.4.21
+ bl LOC(4.21)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (5*2+1), %o2
-L.4.21:
+LOC(4.21):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -212,41 +208,41 @@ L.4.21:
-L.2.17:
+LOC(2.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits 1
- bl L.3.17
+ bl LOC(3.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 3
- bl L.4.19
+ bl LOC(4.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (3*2+1), %o2
-L.4.19:
+LOC(4.19):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (3*2-1), %o2
-L.3.17:
+LOC(3.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 1
- bl L.4.17
+ bl LOC(4.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (1*2+1), %o2
-L.4.17:
+LOC(4.17):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -255,46 +251,46 @@ L.4.17:
-L.1.16:
+LOC(1.16):
! remainder is negative
addcc %o3,%o5,%o3
! depth 2, accumulated bits -1
- bl L.2.15
+ bl LOC(2.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits -1
- bl L.3.15
+ bl LOC(3.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -1
- bl L.4.15
+ bl LOC(4.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-1*2+1), %o2
-L.4.15:
+LOC(4.15):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-1*2-1), %o2
-L.3.15:
+LOC(3.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -3
- bl L.4.13
+ bl LOC(4.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-3*2+1), %o2
-L.4.13:
+LOC(4.13):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -302,41 +298,41 @@ L.4.13:
-L.2.15:
+LOC(2.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits -3
- bl L.3.13
+ bl LOC(3.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -5
- bl L.4.11
+ bl LOC(4.11)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-5*2+1), %o2
-L.4.11:
+LOC(4.11):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-5*2-1), %o2
-L.3.13:
+LOC(3.13):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -7
- bl L.4.9
+ bl LOC(4.9)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-7*2+1), %o2
-L.4.9:
+LOC(4.9):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -346,20 +342,22 @@ L.4.9:
9:
-Lend_regular_divide:
+LOC(end_regular_divide):
subcc %o4, 1, %o4
- bge Ldivloop
+ bge LOC(divloop)
tst %o3
- bl,a Lgot_result
+ bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!)
add %o3, %o1, %o3
-Lgot_result:
+LOC(got_result):
! check to see if answer should be < 0
- tst %g6
+ tst %g3
bl,a 1f
sub %g0, %o3, %o3
1:
retl
mov %o3, %o0
+
+END(.rem)
diff --git a/sysdeps/sparc/rshift.S b/sysdeps/sparc/sparc32/rshift.S
index fea4f3b926..db1d2526cd 100644
--- a/sysdeps/sparc/rshift.S
+++ b/sysdeps/sparc/sparc32/rshift.S
@@ -1,19 +1,19 @@
! sparc __mpn_rshift --
-
-! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
+!
+! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+!
! This file is part of the GNU MP Library.
-
+!
! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
-
+!
! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details.
-
+!
! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -21,28 +21,26 @@
! INPUT PARAMETERS
-! res_ptr %o0
-! src_ptr %o1
-! size %o2
-! cnt %o3
+! RES_PTR %o0
+! SRC_PTR %o1
+! SIZE %o2
+! CNT %o3
-#include "sysdep.h"
+#include <sysdep.h>
- .text
- .align 4
- .global C_SYMBOL_NAME(__mpn_rshift)
-C_SYMBOL_NAME(__mpn_rshift):
+ENTRY(__mpn_rshift)
ld [%o1],%g2 ! load first limb
sub %g0,%o3,%o5 ! negate shift count
add %o2,-1,%o2
andcc %o2,4-1,%g4 ! number of limbs in first loop
sll %g2,%o5,%g1 ! compute function result
- be L0 ! if multiple of 4 limbs, skip first loop
+ be LOC(0) ! if multiple of 4 limbs, skip first loop
st %g1,[%sp+80]
sub %o2,%g4,%o2 ! adjust count for main loop
-Loop0: ld [%o1+4],%g3
+LOC(loop0):
+ ld [%o1+4],%g3
add %o0,4,%o0
add %o1,4,%o1
addcc %g4,-1,%g4
@@ -50,14 +48,15 @@ Loop0: ld [%o1+4],%g3
sll %g3,%o5,%g1
mov %g3,%g2
or %o4,%g1,%o4
- bne Loop0
+ bne LOC(loop0)
st %o4,[%o0-4]
-L0: tst %o2
- be Lend
+LOC(0): tst %o2
+ be LOC(end)
nop
-Loop: ld [%o1+4],%g3
+LOC(loop):
+ ld [%o1+4],%g3
add %o0,16,%o0
addcc %o2,-4,%o2
srl %g2,%o3,%o4
@@ -83,10 +82,13 @@ Loop: ld [%o1+4],%g3
add %o1,16,%o1
or %g4,%g1,%g4
- bne Loop
+ bne LOC(loop)
st %g4,[%o0-4]
-Lend: srl %g2,%o3,%g2
+LOC(end):
+ srl %g2,%o3,%g2
st %g2,[%o0-0]
retl
ld [%sp+80],%o0
+
+END(__mpn_rshift)
diff --git a/sysdeps/sparc/sdiv.S b/sysdeps/sparc/sparc32/sdiv.S
index dadbb36b0a..4b325476d7 100644
--- a/sysdeps/sparc/sdiv.S
+++ b/sysdeps/sparc/sparc32/sdiv.S
@@ -37,18 +37,14 @@
-#include "DEFS.h"
-#ifdef __svr4__
+#include <sysdep.h>
#include <sys/trap.h>
-#else
-#include <machine/trap.h>
-#endif
-FUNC(.div)
+ENTRY(.div)
! compute sign of result; if neither is negative, no problem
orcc %o1, %o0, %g0 ! either negative?
bge 2f ! no, go do the divide
- xor %o1, %o0, %g6 ! compute sign in any case
+ xor %o1, %o0, %g3 ! compute sign in any case
tst %o1
bge 1f
tst %o0
@@ -72,11 +68,11 @@ FUNC(.div)
1:
cmp %o3, %o5 ! if %o1 exceeds %o0, done
- blu Lgot_result ! (and algorithm fails otherwise)
+ blu LOC(got_result) ! (and algorithm fails otherwise)
clr %o2
sethi %hi(1 << (32 - 4 - 1)), %g1
cmp %o3, %g1
- blu Lnot_really_big
+ blu LOC(not_really_big)
clr %o4
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
@@ -87,15 +83,15 @@ FUNC(.div)
1:
cmp %o5, %g1
bgeu 3f
- mov 1, %g7
+ mov 1, %g2
sll %o5, 4, %o5
b 1b
add %o4, 1, %o4
- ! Now compute %g7.
+ ! Now compute %g2.
2: addcc %o5, %o5, %o5
- bcc Lnot_too_big
- add %g7, 1, %g7
+ bcc LOC(not_too_big)
+ add %g2, 1, %g2
! We get here if the %o1 overflowed while shifting.
! This means that %o3 has the high-order bit set.
@@ -103,20 +99,20 @@ FUNC(.div)
sll %g1, 4, %g1 ! high order bit
srl %o5, 1, %o5 ! rest of %o5
add %o5, %g1, %o5
- b Ldo_single_div
- sub %g7, 1, %g7
+ b LOC(do_single_div)
+ sub %g2, 1, %g2
- Lnot_too_big:
+ LOC(not_too_big):
3: cmp %o5, %o3
blu 2b
nop
- be Ldo_single_div
+ be LOC(do_single_div)
nop
/* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */
! %o5 > %o3: went too far: back up 1 step
! srl %o5, 1, %o5
- ! dec %g7
+ ! dec %g2
! do single-bit divide steps
!
! We have to be careful here. We know that %o3 >= %o5, so we can do the
@@ -125,15 +121,15 @@ FUNC(.div)
! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around.
! So we unroll slightly...
- Ldo_single_div:
- subcc %g7, 1, %g7
- bl Lend_regular_divide
+ LOC(do_single_div):
+ subcc %g2, 1, %g2
+ bl LOC(end_regular_divide)
nop
sub %o3, %o5, %o3
mov 1, %o2
- b Lend_single_divloop
+ b LOC(end_single_divloop)
nop
- Lsingle_divloop:
+ LOC(single_divloop):
sll %o2, 1, %o2
bl 1f
srl %o5, 1, %o5
@@ -145,66 +141,66 @@ FUNC(.div)
add %o3, %o5, %o3
sub %o2, 1, %o2
2:
- Lend_single_divloop:
- subcc %g7, 1, %g7
- bge Lsingle_divloop
+ LOC(end_single_divloop):
+ subcc %g2, 1, %g2
+ bge LOC(single_divloop)
tst %o3
- b,a Lend_regular_divide
+ b,a LOC(end_regular_divide)
-Lnot_really_big:
+LOC(not_really_big):
1:
sll %o5, 4, %o5
cmp %o5, %o3
bleu 1b
addcc %o4, 1, %o4
- be Lgot_result
+ be LOC(got_result)
sub %o4, 1, %o4
tst %o3 ! set up for initial iteration
-Ldivloop:
+LOC(divloop):
sll %o2, 4, %o2
! depth 1, accumulated bits 0
- bl L.1.16
+ bl LOC(1.16)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 2, accumulated bits 1
- bl L.2.17
+ bl LOC(2.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits 3
- bl L.3.19
+ bl LOC(3.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 7
- bl L.4.23
+ bl LOC(4.23)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (7*2+1), %o2
-L.4.23:
+LOC(4.23):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (7*2-1), %o2
-L.3.19:
+LOC(3.19):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 5
- bl L.4.21
+ bl LOC(4.21)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (5*2+1), %o2
-L.4.21:
+LOC(4.21):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -212,41 +208,41 @@ L.4.21:
-L.2.17:
+LOC(2.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits 1
- bl L.3.17
+ bl LOC(3.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 3
- bl L.4.19
+ bl LOC(4.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (3*2+1), %o2
-L.4.19:
+LOC(4.19):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (3*2-1), %o2
-L.3.17:
+LOC(3.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 1
- bl L.4.17
+ bl LOC(4.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (1*2+1), %o2
-L.4.17:
+LOC(4.17):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -255,46 +251,46 @@ L.4.17:
-L.1.16:
+LOC(1.16):
! remainder is negative
addcc %o3,%o5,%o3
! depth 2, accumulated bits -1
- bl L.2.15
+ bl LOC(2.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits -1
- bl L.3.15
+ bl LOC(3.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -1
- bl L.4.15
+ bl LOC(4.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-1*2+1), %o2
-L.4.15:
+LOC(4.15):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-1*2-1), %o2
-L.3.15:
+LOC(3.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -3
- bl L.4.13
+ bl LOC(4.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-3*2+1), %o2
-L.4.13:
+LOC(4.13):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -302,41 +298,41 @@ L.4.13:
-L.2.15:
+LOC(2.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits -3
- bl L.3.13
+ bl LOC(3.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -5
- bl L.4.11
+ bl LOC(4.11)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-5*2+1), %o2
-L.4.11:
+LOC(4.11):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-5*2-1), %o2
-L.3.13:
+LOC(3.13):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -7
- bl L.4.9
+ bl LOC(4.9)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-7*2+1), %o2
-L.4.9:
+LOC(4.9):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -346,20 +342,22 @@ L.4.9:
9:
-Lend_regular_divide:
+LOC(end_regular_divide):
subcc %o4, 1, %o4
- bge Ldivloop
+ bge LOC(divloop)
tst %o3
- bl,a Lgot_result
+ bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!)
sub %o2, 1, %o2
-Lgot_result:
+LOC(got_result):
! check to see if answer should be < 0
- tst %g6
+ tst %g3
bl,a 1f
sub %g0, %o2, %o2
1:
retl
mov %o2, %o0
+
+END(.div)
diff --git a/sysdeps/sparc/sparc32/setjmp.S b/sysdeps/sparc/sparc32/setjmp.S
new file mode 100644
index 0000000000..47791c253a
--- /dev/null
+++ b/sysdeps/sparc/sparc32/setjmp.S
@@ -0,0 +1,50 @@
+/* Copyright (C) 1991, 1993, 1994, 1996, 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>
+#include <sys/trap.h>
+
+#define _ASM 1
+#include <jmp_buf.h>
+
+ENTRY(__setjmp)
+ b 1f
+ set 0, %o1
+END(__setjmp)
+
+ENTRY(setjmp)
+ set 1, %o1
+END(setjmp)
+
+ENTRY (__sigsetjmp)
+1:
+ /* Save our PC, SP and FP. Save the signal mask if requested with
+ a tail-call for simplicity; it always returns zero. */
+ ta ST_FLUSH_WINDOWS
+
+ st %o7, [%o0 + (JB_PC * 4)]
+ st %sp, [%o0 + (JB_SP * 4)]
+ st %fp, [%o0 + (JB_FP * 4)]
+
+ mov %o7, %g1
+ call __sigjmp_save
+ mov %g1, %o7
+END(__sigsetjmp)
+
+weak_alias(__setjmp, _setjmp)
+weak_extern(setjmp)
diff --git a/sysdeps/sparc/sparc32/sparcv8/Dist b/sysdeps/sparc/sparc32/sparcv8/Dist
new file mode 100644
index 0000000000..6318172684
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sparcv8/Dist
@@ -0,0 +1,6 @@
+urem.S
+umul.S
+udiv.S
+sdiv.S
+rem.S
+dotmul.S
diff --git a/sysdeps/sparc/sparc8/addmul_1.S b/sysdeps/sparc/sparc32/sparcv8/addmul_1.S
index fb9ea7cf0e..7b871b8e8b 100644
--- a/sysdeps/sparc/sparc8/addmul_1.S
+++ b/sysdeps/sparc/sparc32/sparcv8/addmul_1.S
@@ -27,54 +27,52 @@
! size o2
! s2_limb o3
-#include "sysdep.h"
+#include <sysdep.h>
-.text
- .align 4
- .global C_SYMBOL_NAME(__mpn_addmul_1)
-C_SYMBOL_NAME(__mpn_addmul_1):
- orcc %g0,%g0,%g2
+ENTRY(__mpn_addmul_1)
ld [%o1+0],%o4 ! 1
-
sll %o2,4,%g1
- and %g1,(4-1)<<4,%g1
-#if PIC
+ orcc %g0,%g0,%g2
mov %o7,%g4 ! Save return address register
- call 1f
- add %o7,LL-1f,%g3
-1: mov %g4,%o7 ! Restore return address register
-#else
- sethi %hi(LL),%g3
- or %g3,%lo(LL),%g3
-#endif
- jmp %g3+%g1
- nop
-LL:
-LL00: add %o0,-4,%o0
- b Loop00 /* 4, 8, 12, ... */
- add %o1,-4,%o1
- nop
-LL01: b Loop01 /* 1, 5, 9, ... */
+ and %g1,(4-1)<<4,%g1
+1: call 2f
+ add %o7,3f-1b,%g3
+2: jmp %g3+%g1
+ mov %g4,%o7 ! Restore return address register
+
+ .align 4
+3:
+LOC(00):
+ add %o0,-4,%o0
+ b LOC(loop00) /* 4, 8, 12, ... */
+ add %o1,-4,%o1
nop
+LOC(01):
+ b LOC(loop01) /* 1, 5, 9, ... */
+ nop
nop
nop
-LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
- b Loop10
- add %o1,4,%o1
+LOC(10):
+ add %o0,-12,%o0 /* 2, 6, 10, ... */
+ b LOC(loop10)
+ add %o1,4,%o1
nop
-LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
- b Loop11
- add %o1,-8,%o1
+LOC(11):
+ add %o0,-8,%o0 /* 3, 7, 11, ... */
+ b LOC(loop11)
+ add %o1,-8,%o1
nop
-1: addcc %g3,%g2,%g3 ! 1
+LOC(loop):
+ addcc %g3,%g2,%g3 ! 1
ld [%o1+4],%o4 ! 2
rd %y,%g2 ! 1
addx %g0,%g2,%g2
ld [%o0+0],%g1 ! 2
addcc %g1,%g3,%g3
st %g3,[%o0+0] ! 1
-Loop00: umul %o4,%o3,%g3 ! 2
+LOC(loop00):
+ umul %o4,%o3,%g3 ! 2
ld [%o0+4],%g1 ! 2
addxcc %g3,%g2,%g3 ! 2
ld [%o1+8],%o4 ! 3
@@ -83,7 +81,8 @@ Loop00: umul %o4,%o3,%g3 ! 2
nop
addcc %g1,%g3,%g3
st %g3,[%o0+4] ! 2
-Loop11: umul %o4,%o3,%g3 ! 3
+LOC(loop11):
+ umul %o4,%o3,%g3 ! 3
addxcc %g3,%g2,%g3 ! 3
ld [%o1+12],%o4 ! 4
rd %y,%g2 ! 3
@@ -92,7 +91,8 @@ Loop11: umul %o4,%o3,%g3 ! 3
ld [%o0+8],%g1 ! 2
addcc %g1,%g3,%g3
st %g3,[%o0+8] ! 3
-Loop10: umul %o4,%o3,%g3 ! 4
+LOC(loop10):
+ umul %o4,%o3,%g3 ! 4
addxcc %g3,%g2,%g3 ! 4
ld [%o1+0],%o4 ! 1
rd %y,%g2 ! 4
@@ -102,9 +102,10 @@ Loop10: umul %o4,%o3,%g3 ! 4
st %g3,[%o0+12] ! 4
add %o0,16,%o0
addx %g0,%g2,%g2
-Loop01: addcc %o2,-4,%o2
- bg 1b
- umul %o4,%o3,%g3 ! 1
+LOC(loop01):
+ addcc %o2,-4,%o2
+ bg LOC(loop)
+ umul %o4,%o3,%g3 ! 1
addcc %g3,%g2,%g3 ! 4
rd %y,%g2 ! 4
@@ -112,13 +113,7 @@ Loop01: addcc %o2,-4,%o2
ld [%o0+0],%g1 ! 2
addcc %g1,%g3,%g3
st %g3,[%o0+0] ! 4
- addx %g0,%g2,%o0
-
retl
- nop
-
-
-! umul, ld, addxcc, rd, st
-
-! umul, ld, addxcc, rd, ld, addcc, st, addx
+ addx %g0,%g2,%o0
+END(__mpn_addmul_1)
diff --git a/sysdeps/sparc/sparc32/sparcv8/dotmul.S b/sysdeps/sparc/sparc32/sparcv8/dotmul.S
new file mode 100644
index 0000000000..9b20cc3684
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sparcv8/dotmul.S
@@ -0,0 +1,13 @@
+/*
+ * Sparc v8 has multiply.
+ */
+
+#include <sysdep.h>
+
+ENTRY(.mul)
+
+ smul %o0, %o1, %o0
+ retl
+ rd %y, %o1
+
+END(.mul)
diff --git a/sysdeps/sparc/sparc8/mul_1.S b/sysdeps/sparc/sparc32/sparcv8/mul_1.S
index b641feb453..801e224c15 100644
--- a/sysdeps/sparc/sparc8/mul_1.S
+++ b/sysdeps/sparc/sparc32/sparcv8/mul_1.S
@@ -27,73 +27,77 @@
! size o2
! s2_limb o3
-#include "sysdep.h"
+#include <sysdep.h>
-.text
- .align 8
- .global C_SYMBOL_NAME(__mpn_mul_1)
-C_SYMBOL_NAME(__mpn_mul_1):
+ENTRY(__mpn_mul_1)
sll %o2,4,%g1
- and %g1,(4-1)<<4,%g1
-#if PIC
mov %o7,%g4 ! Save return address register
- call 1f
- add %o7,LL-1f,%g3
-1: mov %g4,%o7 ! Restore return address register
-#else
- sethi %hi(LL),%g3
- or %g3,%lo(LL),%g3
-#endif
+ and %g1,(4-1)<<4,%g1
+1: call 2f
+ add %o7,3f-1b,%g3
+2: mov %g4,%o7 ! Restore return address register
jmp %g3+%g1
- ld [%o1+0],%o4 ! 1
-LL:
-LL00: add %o0,-4,%o0
+ ld [%o1+0],%o4 ! 1
+
+ .align 4
+3:
+LOC(00):
+ 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
+ b LOC(loop00) /* 4, 8, 12, ... */
+ orcc %g0,%g0,%g2
+LOC(01):
+ b LOC(loop01) /* 1, 5, 9, ... */
+ orcc %g0,%g0,%g2
nop
nop
-LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
+LOC(10):
+ add %o0,-12,%o0 /* 2, 6, 10, ... */
add %o1,4,%o1
- b Loop10
- orcc %g0,%g0,%g2
+ b LOC(loop10)
+ orcc %g0,%g0,%g2
nop
-LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
+LOC(11):
+ add %o0,-8,%o0 /* 3, 7, 11, ... */
add %o1,-8,%o1
- b Loop11
- orcc %g0,%g0,%g2
+ b LOC(loop11)
+ orcc %g0,%g0,%g2
-Loop: addcc %g3,%g2,%g3 ! 1
+LOC(loop):
+ addcc %g3,%g2,%g3 ! 1
ld [%o1+4],%o4 ! 2
st %g3,[%o0+0] ! 1
rd %y,%g2 ! 1
-Loop00: umul %o4,%o3,%g3 ! 2
+LOC(loop00):
+ umul %o4,%o3,%g3 ! 2
addxcc %g3,%g2,%g3 ! 2
ld [%o1+8],%o4 ! 3
st %g3,[%o0+4] ! 2
rd %y,%g2 ! 2
-Loop11: umul %o4,%o3,%g3 ! 3
+LOC(loop11):
+ umul %o4,%o3,%g3 ! 3
addxcc %g3,%g2,%g3 ! 3
ld [%o1+12],%o4 ! 4
add %o1,16,%o1
st %g3,[%o0+8] ! 3
rd %y,%g2 ! 3
-Loop10: umul %o4,%o3,%g3 ! 4
+LOC(loop10):
+ umul %o4,%o3,%g3 ! 4
addxcc %g3,%g2,%g3 ! 4
ld [%o1+0],%o4 ! 1
st %g3,[%o0+12] ! 4
add %o0,16,%o0
rd %y,%g2 ! 4
addx %g0,%g2,%g2
-Loop01: addcc %o2,-4,%o2
- bg Loop
- umul %o4,%o3,%g3 ! 1
+LOC(loop01):
+ addcc %o2,-4,%o2
+ bg LOC(loop)
+ umul %o4,%o3,%g3 ! 1
addcc %g3,%g2,%g3 ! 4
st %g3,[%o0+0] ! 4
rd %y,%g2 ! 4
-
retl
- addx %g0,%g2,%o0
+ addx %g0,%g2,%o0
+
+END(__mpn_mul_1)
diff --git a/sysdeps/sparc/sparc32/sparcv8/rem.S b/sysdeps/sparc/sparc32/sparcv8/rem.S
new file mode 100644
index 0000000000..061e80093c
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sparcv8/rem.S
@@ -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)
diff --git a/sysdeps/sparc/sparc32/sparcv8/sdiv.S b/sysdeps/sparc/sparc32/sparcv8/sdiv.S
new file mode 100644
index 0000000000..81c3ac1c97
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sparcv8/sdiv.S
@@ -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)
diff --git a/sysdeps/sparc/sparc8/submul_1.S b/sysdeps/sparc/sparc32/sparcv8/submul_1.S
index e40119d011..c71f228511 100644
--- a/sysdeps/sparc/sparc8/submul_1.S
+++ b/sysdeps/sparc/sparc32/sparcv8/submul_1.S
@@ -27,12 +27,9 @@
! size o2
! s2_limb o3
-#include "sysdep.h"
+#include <sysdep.h>
-.text
- .align 4
- .global C_SYMBOL_NAME(__mpn_submul_1)
-C_SYMBOL_NAME(__mpn_submul_1):
+ENTRY(__mpn_submul_1)
sub %g0,%o2,%o2 ! negate ...
sll %o2,2,%o2 ! ... and scale size
sub %o1,%o2,%o1 ! o1 is offset s1_ptr
@@ -40,7 +37,8 @@ C_SYMBOL_NAME(__mpn_submul_1):
mov 0,%o0 ! clear cy_limb
-Loop: ld [%o1+%o2],%o4
+LOC(loop):
+ ld [%o1+%o2],%o4
ld [%g1+%o2],%g2
umul %o4,%o3,%o5
rd %y,%g3
@@ -51,8 +49,10 @@ Loop: ld [%o1+%o2],%o4
st %g2,[%g1+%o2]
addcc %o2,4,%o2
- bne Loop
+ bne LOC(loop)
nop
retl
nop
+
+END(__mpn_submul_1)
diff --git a/sysdeps/sparc/sparc32/sparcv8/udiv.S b/sysdeps/sparc/sparc32/sparcv8/udiv.S
new file mode 100644
index 0000000000..4e3cddc63f
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sparcv8/udiv.S
@@ -0,0 +1,13 @@
+/*
+ * Sparc v8 has divide.
+ */
+
+#include <sysdep.h>
+
+ENTRY(.udiv)
+
+ wr %g0, 0, %y
+ retl
+ udiv %o0, %o1, %o0
+
+END(.udiv)
diff --git a/sysdeps/sparc/sparc8/udiv_qrnnd.S b/sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S
index 49c2398806..5b0d42923a 100644
--- a/sysdeps/sparc/sparc8/udiv_qrnnd.S
+++ b/sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S
@@ -27,66 +27,75 @@
#include "sysdep.h"
- .text
- .align 4
- .global C_SYMBOL_NAME(__udiv_qrnnd)
-C_SYMBOL_NAME(__udiv_qrnnd):
+ENTRY(__udiv_qrnnd)
tst %o3
- bneg Largedivisor
+ bneg LOC(largedivisor)
mov 8,%g1
- b Lp1
+ b LOC(p1)
addxcc %o2,%o2,%o2
-Lplop: bcc Ln1
+LOC(plop):
+ bcc LOC(n1)
addxcc %o2,%o2,%o2
-Lp1: addx %o1,%o1,%o1
+LOC(p1):
+ addx %o1,%o1,%o1
subcc %o1,%o3,%o4
- bcc Ln2
+ bcc LOC(n2)
addxcc %o2,%o2,%o2
-Lp2: addx %o1,%o1,%o1
+LOC(p2):
+ addx %o1,%o1,%o1
subcc %o1,%o3,%o4
- bcc Ln3
+ bcc LOC(n3)
addxcc %o2,%o2,%o2
-Lp3: addx %o1,%o1,%o1
+LOC(p3):
+ addx %o1,%o1,%o1
subcc %o1,%o3,%o4
- bcc Ln4
+ bcc LOC(n4)
addxcc %o2,%o2,%o2
-Lp4: addx %o1,%o1,%o1
+LOC(p4):
+ addx %o1,%o1,%o1
addcc %g1,-1,%g1
- bne Lplop
+ bne LOC(plop)
subcc %o1,%o3,%o4
- bcc Ln5
+ bcc LOC(n5)
addxcc %o2,%o2,%o2
-Lp5: st %o1,[%o0]
+LOC(p5):
+ st %o1,[%o0]
retl
xnor %g0,%o2,%o0
-Lnlop: bcc Lp1
+LOC(nlop):
+ bcc LOC(p1)
addxcc %o2,%o2,%o2
-Ln1: addx %o4,%o4,%o4
+LOC(n1):
+ addx %o4,%o4,%o4
subcc %o4,%o3,%o1
- bcc Lp2
+ bcc LOC(p2)
addxcc %o2,%o2,%o2
-Ln2: addx %o4,%o4,%o4
+LOC(n2):
+ addx %o4,%o4,%o4
subcc %o4,%o3,%o1
- bcc Lp3
+ bcc LOC(p3)
addxcc %o2,%o2,%o2
-Ln3: addx %o4,%o4,%o4
+LOC(n3):
+ addx %o4,%o4,%o4
subcc %o4,%o3,%o1
- bcc Lp4
+ bcc LOC(p4)
addxcc %o2,%o2,%o2
-Ln4: addx %o4,%o4,%o4
+LOC(n4):
+ addx %o4,%o4,%o4
addcc %g1,-1,%g1
- bne Lnlop
+ bne LOC(nlop)
subcc %o4,%o3,%o1
- bcc Lp5
+ bcc LOC(p5)
addxcc %o2,%o2,%o2
-Ln5: st %o4,[%o0]
+LOC(n5):
+ st %o4,[%o0]
retl
xnor %g0,%o2,%o0
-Largedivisor:
+LOC(largedivisor):
and %o2,1,%o5 ! %o5 = n0 & 1
srl %o2,1,%o2
@@ -98,89 +107,109 @@ Largedivisor:
srl %o3,1,%g3 ! %g3 = floor(d / 2)
add %g3,%g2,%g3 ! %g3 = ceil(d / 2)
- b LLp1
+ b LOC(Lp1)
addxcc %o2,%o2,%o2
-LLplop: bcc LLn1
+LOC(Lplop):
+ bcc LOC(Ln1)
addxcc %o2,%o2,%o2
-LLp1: addx %o1,%o1,%o1
+LOC(Lp1):
+ addx %o1,%o1,%o1
subcc %o1,%g3,%o4
- bcc LLn2
+ bcc LOC(Ln2)
addxcc %o2,%o2,%o2
-LLp2: addx %o1,%o1,%o1
+LOC(Lp2):
+ addx %o1,%o1,%o1
subcc %o1,%g3,%o4
- bcc LLn3
+ bcc LOC(Ln3)
addxcc %o2,%o2,%o2
-LLp3: addx %o1,%o1,%o1
+LOC(Lp3):
+ addx %o1,%o1,%o1
subcc %o1,%g3,%o4
- bcc LLn4
+ bcc LOC(Ln4)
addxcc %o2,%o2,%o2
-LLp4: addx %o1,%o1,%o1
+LOC(Lp4):
+ addx %o1,%o1,%o1
addcc %g1,-1,%g1
- bne LLplop
+ bne LOC(Lplop)
subcc %o1,%g3,%o4
- bcc LLn5
+ bcc LOC(Ln5)
addxcc %o2,%o2,%o2
-LLp5: add %o1,%o1,%o1 ! << 1
+LOC(Lp5):
+ add %o1,%o1,%o1 ! << 1
tst %g2
- bne Oddp
+ bne LOC(Oddp)
add %o5,%o1,%o1
st %o1,[%o0]
retl
xnor %g0,%o2,%o0
-LLnlop: bcc LLp1
+LOC(Lnlop):
+ bcc LOC(Lp1)
addxcc %o2,%o2,%o2
-LLn1: addx %o4,%o4,%o4
+LOC(Ln1):
+ addx %o4,%o4,%o4
subcc %o4,%g3,%o1
- bcc LLp2
+ bcc LOC(Lp2)
addxcc %o2,%o2,%o2
-LLn2: addx %o4,%o4,%o4
+LOC(Ln2):
+ addx %o4,%o4,%o4
subcc %o4,%g3,%o1
- bcc LLp3
+ bcc LOC(Lp3)
addxcc %o2,%o2,%o2
-LLn3: addx %o4,%o4,%o4
+LOC(Ln3):
+ addx %o4,%o4,%o4
subcc %o4,%g3,%o1
- bcc LLp4
+ bcc LOC(Lp4)
addxcc %o2,%o2,%o2
-LLn4: addx %o4,%o4,%o4
+LOC(Ln4):
+ addx %o4,%o4,%o4
addcc %g1,-1,%g1
- bne LLnlop
+ bne LOC(Lnlop)
subcc %o4,%g3,%o1
- bcc LLp5
+ bcc LOC(Lp5)
addxcc %o2,%o2,%o2
-LLn5: add %o4,%o4,%o4 ! << 1
+LOC(Ln5):
+ add %o4,%o4,%o4 ! << 1
tst %g2
- bne Oddn
+ bne LOC(Oddn)
add %o5,%o4,%o4
st %o4,[%o0]
retl
xnor %g0,%o2,%o0
-Oddp: xnor %g0,%o2,%o2
+LOC(Oddp):
+ xnor %g0,%o2,%o2
! q' in %o2. r' in %o1
addcc %o1,%o2,%o1
- bcc LLp6
+ bcc LOC(Lp6)
addx %o2,0,%o2
sub %o1,%o3,%o1
-LLp6: subcc %o1,%o3,%g0
- bcs LLp7
+LOC(Lp6):
+ subcc %o1,%o3,%g0
+ bcs LOC(Lp7)
subx %o2,-1,%o2
sub %o1,%o3,%o1
-LLp7: st %o1,[%o0]
+LOC(Lp7):
+ st %o1,[%o0]
retl
mov %o2,%o0
-Oddn: xnor %g0,%o2,%o2
+LOC(Oddn):
+ xnor %g0,%o2,%o2
! q' in %o2. r' in %o4
addcc %o4,%o2,%o4
- bcc LLn6
+ bcc LOC(Ln6)
addx %o2,0,%o2
sub %o4,%o3,%o4
-LLn6: subcc %o4,%o3,%g0
- bcs LLn7
+LOC(Ln6):
+ subcc %o4,%o3,%g0
+ bcs LOC(Ln7)
subx %o2,-1,%o2
sub %o4,%o3,%o4
-LLn7: st %o4,[%o0]
+LOC(Ln7):
+ st %o4,[%o0]
retl
mov %o2,%o0
+
+END(__udiv_qrnnd)
diff --git a/sysdeps/sparc/sparc32/sparcv8/umul.S b/sysdeps/sparc/sparc32/sparcv8/umul.S
new file mode 100644
index 0000000000..cec454a7dd
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sparcv8/umul.S
@@ -0,0 +1,13 @@
+/*
+ * Sparc v8 has multiply.
+ */
+
+#include <sysdep.h>
+
+ENTRY(.umul)
+
+ umul %o0, %o1, %o0
+ retl
+ rd %y, %o1
+
+END(.umul)
diff --git a/sysdeps/sparc/sparc32/sparcv8/urem.S b/sysdeps/sparc/sparc32/sparcv8/urem.S
new file mode 100644
index 0000000000..81e123f3da
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sparcv8/urem.S
@@ -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)
diff --git a/sysdeps/sparc/sparc32/sub_n.S b/sysdeps/sparc/sparc32/sub_n.S
new file mode 100644
index 0000000000..74400600bd
--- /dev/null
+++ b/sysdeps/sparc/sparc32/sub_n.S
@@ -0,0 +1,329 @@
+! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+! store difference in a third limb vector.
+!
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+#define RES_PTR %o0
+#define S1_PTR %o1
+#define S2_PTR %o2
+#define SIZE %o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_sub_n)
+ xor S2_PTR,RES_PTR,%g1
+ andcc %g1,4,%g0
+ bne LOC(1) ! branch if alignment differs
+ nop
+! ** V1a **
+ andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
+ be LOC(v1) ! if no, branch
+ nop
+/* Add least significant limb separately to align RES_PTR and S2_PTR */
+ ld [S1_PTR],%g4
+ add S1_PTR,4,S1_PTR
+ ld [S2_PTR],%g2
+ add S2_PTR,4,S2_PTR
+ add SIZE,-1,SIZE
+ subcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+LOC(v1):
+ addx %g0,%g0,%o4 ! save cy in register
+ cmp SIZE,2 ! if SIZE < 2 ...
+ bl LOC(end2) ! ... branch to tail code
+ subcc %g0,%o4,%g0 ! restore cy
+
+ ld [S1_PTR+0],%g4
+ addcc SIZE,-10,SIZE
+ ld [S1_PTR+4],%g1
+ ldd [S2_PTR+0],%g2
+ blt LOC(fin1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop1):
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+8],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+12],%g1
+ ldd [S2_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+16],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+20],%g1
+ ldd [S2_PTR+16],%g2
+ std %o4,[RES_PTR+8]
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+24],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+28],%g1
+ ldd [S2_PTR+24],%g2
+ std %o4,[RES_PTR+16]
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+32],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+36],%g1
+ ldd [S2_PTR+32],%g2
+ std %o4,[RES_PTR+24]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop1)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin1):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+LOC(loope1):
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+8],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+12],%g1
+ ldd [S2_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope1)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end1):
+ subxcc %g4,%g2,%o4
+ subxcc %g1,%g3,%o5
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+
+ andcc SIZE,1,%g0
+ be LOC(ret1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+ ld [S1_PTR+8],%g4
+ ld [S2_PTR+8],%g2
+ subxcc %g4,%g2,%o4
+ st %o4,[RES_PTR+8]
+
+LOC(ret1):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+LOC(1): xor S1_PTR,RES_PTR,%g1
+ andcc %g1,4,%g0
+ bne LOC(2)
+ nop
+! ** V1b **
+ andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
+ be LOC(v1b) ! if no, branch
+ nop
+/* Add least significant limb separately to align RES_PTR and S1_PTR */
+ ld [S2_PTR],%g4
+ add S2_PTR,4,S2_PTR
+ ld [S1_PTR],%g2
+ add S1_PTR,4,S1_PTR
+ add SIZE,-1,SIZE
+ subcc %g2,%g4,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+LOC(v1b):
+ addx %g0,%g0,%o4 ! save cy in register
+ cmp SIZE,2 ! if SIZE < 2 ...
+ bl LOC(end2) ! ... branch to tail code
+ subcc %g0,%o4,%g0 ! restore cy
+
+ ld [S2_PTR+0],%g4
+ addcc SIZE,-10,SIZE
+ ld [S2_PTR+4],%g1
+ ldd [S1_PTR+0],%g2
+ blt LOC(fin1b)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop1b):
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+8],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+12],%g1
+ ldd [S1_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+16],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+20],%g1
+ ldd [S1_PTR+16],%g2
+ std %o4,[RES_PTR+8]
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+24],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+28],%g1
+ ldd [S1_PTR+24],%g2
+ std %o4,[RES_PTR+16]
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+32],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+36],%g1
+ ldd [S1_PTR+32],%g2
+ std %o4,[RES_PTR+24]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop1b)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin1b):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end1b)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+LOC(loope1b):
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+8],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+12],%g1
+ ldd [S1_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope1b)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end1b):
+ subxcc %g2,%g4,%o4
+ subxcc %g3,%g1,%o5
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+
+ andcc SIZE,1,%g0
+ be LOC(ret1b)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+ ld [S2_PTR+8],%g4
+ ld [S1_PTR+8],%g2
+ subxcc %g2,%g4,%o4
+ st %o4,[RES_PTR+8]
+
+LOC(ret1b):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+! ** V2 **
+/* If we come here, the alignment of S1_PTR and RES_PTR as well as the
+ alignment of S2_PTR and RES_PTR differ. Since there are only two ways
+ things can be aligned (that we care about) we now know that the alignment
+ of S1_PTR and S2_PTR are the same. */
+
+LOC(2): cmp SIZE,1
+ be LOC(jone)
+ nop
+ andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
+ be LOC(v2) ! if no, branch
+ nop
+/* Add least significant limb separately to align S1_PTR and S2_PTR */
+ ld [S1_PTR],%g4
+ add S1_PTR,4,S1_PTR
+ ld [S2_PTR],%g2
+ add S2_PTR,4,S2_PTR
+ add SIZE,-1,SIZE
+ subcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+
+LOC(v2):
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ blt LOC(fin2)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop2):
+ ldd [S1_PTR+0],%g2
+ ldd [S2_PTR+0],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+0]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+4]
+ ldd [S1_PTR+8],%g2
+ ldd [S2_PTR+8],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+8]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+12]
+ ldd [S1_PTR+16],%g2
+ ldd [S2_PTR+16],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+16]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+20]
+ ldd [S1_PTR+24],%g2
+ ldd [S2_PTR+24],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+24]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+28]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop2)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin2):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end2)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(loope2):
+ ldd [S1_PTR+0],%g2
+ ldd [S2_PTR+0],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+0]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+4]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope2)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end2):
+ andcc SIZE,1,%g0
+ be LOC(ret2)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+LOC(jone):
+ ld [S1_PTR],%g4
+ ld [S2_PTR],%g2
+ subxcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+
+LOC(ret2):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+END(__mpn_sub_n)
diff --git a/sysdeps/sparc/submul_1.S b/sysdeps/sparc/sparc32/submul_1.S
index a8ebd501a7..805699b7b2 100644
--- a/sysdeps/sparc/submul_1.S
+++ b/sysdeps/sparc/sparc32/submul_1.S
@@ -1,20 +1,20 @@
! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
! the result from a second limb vector.
-
-! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
-
+!
+! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+!
! This file is part of the GNU MP Library.
-
+!
! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
-
+!
! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details.
-
+!
! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -22,17 +22,14 @@
! INPUT PARAMETERS
-! res_ptr o0
-! s1_ptr o1
-! size o2
-! s2_limb o3
+! RES_PTR o0
+! S1_PTR o1
+! SIZE o2
+! S2_LIMB o3
-#include "sysdep.h"
+#include <sysdep.h>
-.text
- .align 4
- .global C_SYMBOL_NAME(__mpn_submul_1)
-C_SYMBOL_NAME(__mpn_submul_1):
+ENTRY(__mpn_submul_1)
! Make S1_PTR and RES_PTR point at the end of their blocks
! and put (- 4 x SIZE) in index/loop counter.
sll %o2,2,%o2
@@ -41,19 +38,19 @@ C_SYMBOL_NAME(__mpn_submul_1):
sub %g0,%o2,%o2
cmp %o3,0xfff
- bgu Large
+ bgu LOC(large)
nop
ld [%o1+%o2],%o5
mov 0,%o0
- b L0
+ b LOC(0)
add %o4,-4,%o4
-Loop0:
+LOC(loop0):
subcc %o5,%g1,%g1
ld [%o1+%o2],%o5
addx %o0,%g0,%o0
st %g1,[%o4+%o2]
-L0: wr %g0,%o3,%y
+LOC(0): wr %g0,%o3,%y
sra %o5,31,%g2
and %o3,%g2,%g2
andcc %g1,0,%g1
@@ -79,7 +76,7 @@ L0: wr %g0,%o3,%y
addcc %g1,%o0,%g1
addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
addcc %o2,4,%o2 ! loop counter
- bne Loop0
+ bne LOC(loop0)
ld [%o4+%o2],%o5
subcc %o5,%g1,%g1
@@ -88,17 +85,18 @@ L0: wr %g0,%o3,%y
st %g1,[%o4+%o2]
-Large: ld [%o1+%o2],%o5
+LOC(large):
+ ld [%o1+%o2],%o5
mov 0,%o0
sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
- b L1
+ b LOC(1)
add %o4,-4,%o4
-Loop:
+LOC(loop):
subcc %o5,%g3,%g3
ld [%o1+%o2],%o5
addx %o0,%g0,%o0
st %g3,[%o4+%o2]
-L1: wr %g0,%o5,%y
+LOC(1): wr %g0,%o5,%y
and %o5,%g4,%g2
andcc %g0,%g0,%g1
mulscc %g1,%o3,%g1
@@ -138,10 +136,12 @@ L1: wr %g0,%o5,%y
addcc %g3,%o0,%g3
addx %g2,%g1,%o0
addcc %o2,4,%o2
- bne Loop
+ bne LOC(loop)
ld [%o4+%o2],%o5
subcc %o5,%g3,%g3
addx %o0,%g0,%o0
retl
st %g3,[%o4+%o2]
+
+END(__mpn_submul_1)
diff --git a/sysdeps/sparc/udiv.S b/sysdeps/sparc/sparc32/udiv.S
index 826d01183d..0dd48f32b5 100644
--- a/sysdeps/sparc/udiv.S
+++ b/sysdeps/sparc/sparc32/udiv.S
@@ -37,14 +37,10 @@
-#include "DEFS.h"
-#ifdef __svr4__
+#include <sysdep.h>
#include <sys/trap.h>
-#else
-#include <machine/trap.h>
-#endif
-FUNC(.udiv)
+ENTRY(.udiv)
! Ready to divide. Compute size of quotient; scale comparand.
orcc %o1, %g0, %o5
@@ -59,11 +55,11 @@ FUNC(.udiv)
1:
cmp %o3, %o5 ! if %o1 exceeds %o0, done
- blu Lgot_result ! (and algorithm fails otherwise)
+ blu LOC(got_result) ! (and algorithm fails otherwise)
clr %o2
sethi %hi(1 << (32 - 4 - 1)), %g1
cmp %o3, %g1
- blu Lnot_really_big
+ blu LOC(not_really_big)
clr %o4
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
@@ -74,15 +70,15 @@ FUNC(.udiv)
1:
cmp %o5, %g1
bgeu 3f
- mov 1, %g7
+ mov 1, %g2
sll %o5, 4, %o5
b 1b
add %o4, 1, %o4
- ! Now compute %g7.
+ ! Now compute %g2.
2: addcc %o5, %o5, %o5
- bcc Lnot_too_big
- add %g7, 1, %g7
+ bcc LOC(not_too_big)
+ add %g2, 1, %g2
! We get here if the %o1 overflowed while shifting.
! This means that %o3 has the high-order bit set.
@@ -90,20 +86,20 @@ FUNC(.udiv)
sll %g1, 4, %g1 ! high order bit
srl %o5, 1, %o5 ! rest of %o5
add %o5, %g1, %o5
- b Ldo_single_div
- sub %g7, 1, %g7
+ b LOC(do_single_div)
+ sub %g2, 1, %g2
- Lnot_too_big:
+ LOC(not_too_big):
3: cmp %o5, %o3
blu 2b
nop
- be Ldo_single_div
+ be LOC(do_single_div)
nop
/* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */
! %o5 > %o3: went too far: back up 1 step
! srl %o5, 1, %o5
- ! dec %g7
+ ! dec %g2
! do single-bit divide steps
!
! We have to be careful here. We know that %o3 >= %o5, so we can do the
@@ -112,15 +108,15 @@ FUNC(.udiv)
! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around.
! So we unroll slightly...
- Ldo_single_div:
- subcc %g7, 1, %g7
- bl Lend_regular_divide
+ LOC(do_single_div):
+ subcc %g2, 1, %g2
+ bl LOC(end_regular_divide)
nop
sub %o3, %o5, %o3
mov 1, %o2
- b Lend_single_divloop
+ b LOC(end_single_divloop)
nop
- Lsingle_divloop:
+ LOC(single_divloop):
sll %o2, 1, %o2
bl 1f
srl %o5, 1, %o5
@@ -132,66 +128,66 @@ FUNC(.udiv)
add %o3, %o5, %o3
sub %o2, 1, %o2
2:
- Lend_single_divloop:
- subcc %g7, 1, %g7
- bge Lsingle_divloop
+ LOC(end_single_divloop):
+ subcc %g2, 1, %g2
+ bge LOC(single_divloop)
tst %o3
- b,a Lend_regular_divide
+ b,a LOC(end_regular_divide)
-Lnot_really_big:
+LOC(not_really_big):
1:
sll %o5, 4, %o5
cmp %o5, %o3
bleu 1b
addcc %o4, 1, %o4
- be Lgot_result
+ be LOC(got_result)
sub %o4, 1, %o4
tst %o3 ! set up for initial iteration
-Ldivloop:
+LOC(divloop):
sll %o2, 4, %o2
! depth 1, accumulated bits 0
- bl L.1.16
+ bl LOC(1.16)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 2, accumulated bits 1
- bl L.2.17
+ bl LOC(2.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits 3
- bl L.3.19
+ bl LOC(3.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 7
- bl L.4.23
+ bl LOC(4.23)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (7*2+1), %o2
-L.4.23:
+LOC(4.23):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (7*2-1), %o2
-L.3.19:
+LOC(3.19):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 5
- bl L.4.21
+ bl LOC(4.21)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (5*2+1), %o2
-L.4.21:
+LOC(4.21):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -199,41 +195,41 @@ L.4.21:
-L.2.17:
+LOC(2.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits 1
- bl L.3.17
+ bl LOC(3.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 3
- bl L.4.19
+ bl LOC(4.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (3*2+1), %o2
-L.4.19:
+LOC(4.19):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (3*2-1), %o2
-L.3.17:
+LOC(3.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 1
- bl L.4.17
+ bl LOC(4.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (1*2+1), %o2
-L.4.17:
+LOC(4.17):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -242,46 +238,46 @@ L.4.17:
-L.1.16:
+LOC(1.16):
! remainder is negative
addcc %o3,%o5,%o3
! depth 2, accumulated bits -1
- bl L.2.15
+ bl LOC(2.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits -1
- bl L.3.15
+ bl LOC(3.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -1
- bl L.4.15
+ bl LOC(4.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-1*2+1), %o2
-L.4.15:
+LOC(4.15):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-1*2-1), %o2
-L.3.15:
+LOC(3.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -3
- bl L.4.13
+ bl LOC(4.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-3*2+1), %o2
-L.4.13:
+LOC(4.13):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -289,41 +285,41 @@ L.4.13:
-L.2.15:
+LOC(2.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits -3
- bl L.3.13
+ bl LOC(3.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -5
- bl L.4.11
+ bl LOC(4.11)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-5*2+1), %o2
-L.4.11:
+LOC(4.11):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-5*2-1), %o2
-L.3.13:
+LOC(3.13):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -7
- bl L.4.9
+ bl LOC(4.9)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-7*2+1), %o2
-L.4.9:
+LOC(4.9):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -333,16 +329,18 @@ L.4.9:
9:
-Lend_regular_divide:
+LOC(end_regular_divide):
subcc %o4, 1, %o4
- bge Ldivloop
+ bge LOC(divloop)
tst %o3
- bl,a Lgot_result
+ bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!)
sub %o2, 1, %o2
-Lgot_result:
+LOC(got_result):
retl
mov %o2, %o0
+
+END(.udiv)
diff --git a/sysdeps/sparc/udiv_qrnnd.S b/sysdeps/sparc/sparc32/udiv_qrnnd.S
index 4cd4f051b3..2fbb8a5f54 100644
--- a/sysdeps/sparc/udiv_qrnnd.S
+++ b/sysdeps/sparc/sparc32/udiv_qrnnd.S
@@ -1,88 +1,111 @@
! SPARC __udiv_qrnnd division support, used from longlong.h.
-
-! Copyright (C) 1993, 1994 Free Software Foundation, Inc.
-
+!
+! Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
+!
! This file is part of the GNU MP Library.
-
+!
! The GNU MP Library is free software; you can redistribute it and/or modify
! it under the terms of the GNU Library General Public License as published by
! the Free Software Foundation; either version 2 of the License, or (at your
! option) any later version.
-
+!
! The GNU MP Library is distributed in the hope that it will be useful, but
! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! License for more details.
-
+!
! You should have received a copy of the GNU Library General Public License
! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
+!
+! Added PIC support - May/96, Miguel de Icaza
+!
! INPUT PARAMETERS
! rem_ptr i0
! n1 i1
! n0 i2
! d i3
-#include "sysdep.h"
+#include <sysdep.h>
#undef ret /* Kludge for glibc */
+#ifdef PIC
.text
+#else
+ .section .rodata,#alloc
+#endif
.align 8
-LC0: .double 0r4294967296
-LC1: .double 0r2147483648
- .align 4
- .global C_SYMBOL_NAME(__udiv_qrnnd)
-C_SYMBOL_NAME(__udiv_qrnnd):
+ .type two_to_32,@object
+ .size two_to_32,8
+two_to_32:
+ .double 0r4294967296
+
+ .type two_to_31,@object
+ .size two_to_31,8
+two_to_31:
+ .double 0r2147483648
+
+ .text
+ENTRY(__udiv_qrnnd)
!#PROLOGUE# 0
save %sp,-104,%sp
!#PROLOGUE# 1
st %i1,[%fp-8]
ld [%fp-8],%f10
- sethi %hi(LC0),%o7
+#ifdef PIC
+LOC(base):
+ call 1f
+ fitod %f10,%f4
+1: ldd [%o7-(LOC(base)-two_to_32)],%f8
+#else
+ sethi %hi(two_to_32),%o7
fitod %f10,%f4
- ldd [%o7+%lo(LC0)],%f8
+ ldd [%o7+%lo(two_to_32)],%f8
+#endif
cmp %i1,0
- bge L248
+ bge LOC(248)
mov %i0,%i5
faddd %f4,%f8,%f4
-L248:
+LOC(248):
st %i2,[%fp-8]
ld [%fp-8],%f10
fmuld %f4,%f8,%f6
cmp %i2,0
- bge L249
+ bge LOC(249)
fitod %f10,%f2
faddd %f2,%f8,%f2
-L249:
+LOC(249):
st %i3,[%fp-8]
faddd %f6,%f2,%f2
ld [%fp-8],%f10
cmp %i3,0
- bge L250
+ bge LOC(250)
fitod %f10,%f4
faddd %f4,%f8,%f4
-L250:
+LOC(250):
fdivd %f2,%f4,%f2
- sethi %hi(LC1),%o7
- ldd [%o7+%lo(LC1)],%f4
+#ifdef PIC
+ ldd [%o7-(LOC(base)-two_to_31)],%f4
+#else
+ sethi %hi(two_to_31),%o7
+ ldd [%o7+%lo(two_to_31)],%f4
+#endif
fcmped %f2,%f4
nop
- fbge,a L251
+ fbge,a LOC(251)
fsubd %f2,%f4,%f2
fdtoi %f2,%f2
st %f2,[%fp-8]
- b L252
+ b LOC(252)
ld [%fp-8],%i4
-L251:
+LOC(251):
fdtoi %f2,%f2
st %f2,[%fp-8]
ld [%fp-8],%i4
sethi %hi(-2147483648),%g2
xor %i4,%g2,%i4
-L252:
+LOC(252):
wr %g0,%i4,%y
sra %i3,31,%g2
and %i4,%g2,%g2
@@ -124,7 +147,7 @@ L252:
rd %y,%g3
subcc %i2,%g3,%o7
subxcc %i1,%i0,%g0
- be L253
+ be LOC(253)
cmp %o7,%i3
add %i4,-1,%i0
@@ -132,12 +155,14 @@ L252:
st %o7,[%i5]
ret
restore
-L253:
- blu L246
+LOC(253):
+ blu LOC(246)
mov %i4,%i0
add %i4,1,%i0
sub %o7,%i3,%o7
-L246:
+LOC(246):
st %o7,[%i5]
ret
restore
+
+END(__udiv_qrnnd)
diff --git a/sysdeps/sparc/umul.S b/sysdeps/sparc/sparc32/umul.S
index 7a26c295cb..096554a2bc 100644
--- a/sysdeps/sparc/umul.S
+++ b/sysdeps/sparc/sparc32/umul.S
@@ -14,13 +14,14 @@
* bnz overflow (or tnz)
*/
-#include "DEFS.h"
-FUNC(.umul)
+#include <sysdep.h>
+
+ENTRY(.umul)
or %o0, %o1, %o4
- mov %o0, %y ! multiplier -> Y
- andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
- be Lmul_shortway ! if zero, can do it the short way
- andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
+ mov %o0, %y ! multiplier -> Y
+ andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
+ be LOC(mul_shortway) ! if zero, can do it the short way
+ andcc %g0, %g0, %o4 ! zero the partial product; clear N & V
/*
* Long multiply. 32 steps, followed by a final shift step.
@@ -59,7 +60,6 @@ FUNC(.umul)
mulscc %o4, %o1, %o4 ! 32
mulscc %o4, %g0, %o4 ! final shift
-
/*
* Normally, with the shift-and-add approach, if both numbers are
* positive you get the correct result. With 32-bit two's-complement
@@ -97,20 +97,20 @@ FUNC(.umul)
#if 0
tst %o1
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
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
/* Faster code from tege@sics.se. */
sra %o1, 31, %o2 ! make mask from sign bit
and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1
rd %y, %o0 ! get lower half of product
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
-Lmul_shortway:
+LOC(mul_shortway):
/*
* Short multiply. 12 steps, followed by a final shift step.
* The resulting bits are off by 12 and (32-12) = 20 bit positions,
@@ -150,4 +150,6 @@ Lmul_shortway:
srl %o5, 20, %o5 ! shift low bits right 20
or %o5, %o0, %o0
retl
- addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
+ addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
+
+END(.umul)
diff --git a/sysdeps/sparc/urem.S b/sysdeps/sparc/sparc32/urem.S
index 9f64c8859e..5644e7a892 100644
--- a/sysdeps/sparc/urem.S
+++ b/sysdeps/sparc/sparc32/urem.S
@@ -37,14 +37,10 @@
-#include "DEFS.h"
-#ifdef __svr4__
+#include <sysdep.h>
#include <sys/trap.h>
-#else
-#include <machine/trap.h>
-#endif
-FUNC(.urem)
+ENTRY(.urem)
! Ready to divide. Compute size of quotient; scale comparand.
orcc %o1, %g0, %o5
@@ -59,11 +55,11 @@ FUNC(.urem)
1:
cmp %o3, %o5 ! if %o1 exceeds %o0, done
- blu Lgot_result ! (and algorithm fails otherwise)
+ blu LOC(got_result) ! (and algorithm fails otherwise)
clr %o2
sethi %hi(1 << (32 - 4 - 1)), %g1
cmp %o3, %g1
- blu Lnot_really_big
+ blu LOC(not_really_big)
clr %o4
! Here the dividend is >= 2**(31-N) or so. We must be careful here,
@@ -74,15 +70,15 @@ FUNC(.urem)
1:
cmp %o5, %g1
bgeu 3f
- mov 1, %g7
+ mov 1, %g2
sll %o5, 4, %o5
b 1b
add %o4, 1, %o4
- ! Now compute %g7.
+ ! Now compute %g2.
2: addcc %o5, %o5, %o5
- bcc Lnot_too_big
- add %g7, 1, %g7
+ bcc LOC(not_too_big)
+ add %g2, 1, %g2
! We get here if the %o1 overflowed while shifting.
! This means that %o3 has the high-order bit set.
@@ -90,20 +86,20 @@ FUNC(.urem)
sll %g1, 4, %g1 ! high order bit
srl %o5, 1, %o5 ! rest of %o5
add %o5, %g1, %o5
- b Ldo_single_div
- sub %g7, 1, %g7
+ b LOC(do_single_div)
+ sub %g2, 1, %g2
- Lnot_too_big:
+ LOC(not_too_big):
3: cmp %o5, %o3
blu 2b
nop
- be Ldo_single_div
+ be LOC(do_single_div)
nop
/* NB: these are commented out in the V8-Sparc manual as well */
/* (I do not understand this) */
! %o5 > %o3: went too far: back up 1 step
! srl %o5, 1, %o5
- ! dec %g7
+ ! dec %g2
! do single-bit divide steps
!
! We have to be careful here. We know that %o3 >= %o5, so we can do the
@@ -112,15 +108,15 @@ FUNC(.urem)
! order bit set in the first step, just falling into the regular
! division loop will mess up the first time around.
! So we unroll slightly...
- Ldo_single_div:
- subcc %g7, 1, %g7
- bl Lend_regular_divide
+ LOC(do_single_div):
+ subcc %g2, 1, %g2
+ bl LOC(end_regular_divide)
nop
sub %o3, %o5, %o3
mov 1, %o2
- b Lend_single_divloop
+ b LOC(end_single_divloop)
nop
- Lsingle_divloop:
+ LOC(single_divloop):
sll %o2, 1, %o2
bl 1f
srl %o5, 1, %o5
@@ -132,66 +128,66 @@ FUNC(.urem)
add %o3, %o5, %o3
sub %o2, 1, %o2
2:
- Lend_single_divloop:
- subcc %g7, 1, %g7
- bge Lsingle_divloop
+ LOC(end_single_divloop):
+ subcc %g2, 1, %g2
+ bge LOC(single_divloop)
tst %o3
- b,a Lend_regular_divide
+ b,a LOC(end_regular_divide)
-Lnot_really_big:
+LOC(not_really_big):
1:
sll %o5, 4, %o5
cmp %o5, %o3
bleu 1b
addcc %o4, 1, %o4
- be Lgot_result
+ be LOC(got_result)
sub %o4, 1, %o4
tst %o3 ! set up for initial iteration
-Ldivloop:
+LOC(divloop):
sll %o2, 4, %o2
! depth 1, accumulated bits 0
- bl L.1.16
+ bl LOC(1.16)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 2, accumulated bits 1
- bl L.2.17
+ bl LOC(2.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits 3
- bl L.3.19
+ bl LOC(3.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 7
- bl L.4.23
+ bl LOC(4.23)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (7*2+1), %o2
-L.4.23:
+LOC(4.23):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (7*2-1), %o2
-L.3.19:
+LOC(3.19):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 5
- bl L.4.21
+ bl LOC(4.21)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (5*2+1), %o2
-L.4.21:
+LOC(4.21):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -199,41 +195,41 @@ L.4.21:
-L.2.17:
+LOC(2.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits 1
- bl L.3.17
+ bl LOC(3.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits 3
- bl L.4.19
+ bl LOC(4.19)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (3*2+1), %o2
-L.4.19:
+LOC(4.19):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (3*2-1), %o2
-L.3.17:
+LOC(3.17):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits 1
- bl L.4.17
+ bl LOC(4.17)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (1*2+1), %o2
-L.4.17:
+LOC(4.17):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -242,46 +238,46 @@ L.4.17:
-L.1.16:
+LOC(1.16):
! remainder is negative
addcc %o3,%o5,%o3
! depth 2, accumulated bits -1
- bl L.2.15
+ bl LOC(2.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 3, accumulated bits -1
- bl L.3.15
+ bl LOC(3.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -1
- bl L.4.15
+ bl LOC(4.15)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-1*2+1), %o2
-L.4.15:
+LOC(4.15):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-1*2-1), %o2
-L.3.15:
+LOC(3.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -3
- bl L.4.13
+ bl LOC(4.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-3*2+1), %o2
-L.4.13:
+LOC(4.13):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -289,41 +285,41 @@ L.4.13:
-L.2.15:
+LOC(2.15):
! remainder is negative
addcc %o3,%o5,%o3
! depth 3, accumulated bits -3
- bl L.3.13
+ bl LOC(3.13)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
! depth 4, accumulated bits -5
- bl L.4.11
+ bl LOC(4.11)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-5*2+1), %o2
-L.4.11:
+LOC(4.11):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
add %o2, (-5*2-1), %o2
-L.3.13:
+LOC(3.13):
! remainder is negative
addcc %o3,%o5,%o3
! depth 4, accumulated bits -7
- bl L.4.9
+ bl LOC(4.9)
srl %o5,1,%o5
! remainder is positive
subcc %o3,%o5,%o3
b 9f
add %o2, (-7*2+1), %o2
-L.4.9:
+LOC(4.9):
! remainder is negative
addcc %o3,%o5,%o3
b 9f
@@ -333,16 +329,18 @@ L.4.9:
9:
-Lend_regular_divide:
+LOC(end_regular_divide):
subcc %o4, 1, %o4
- bge Ldivloop
+ bge LOC(divloop)
tst %o3
- bl,a Lgot_result
+ bl,a LOC(got_result)
! non-restoring fixup here (one instruction only!)
add %o3, %o1, %o3
-Lgot_result:
+LOC(got_result):
retl
mov %o3, %o0
+
+END(.urem)
diff --git a/sysdeps/sparc/sparc64/Implies b/sysdeps/sparc/sparc64/Implies
new file mode 100644
index 0000000000..a8cae95f9d
--- /dev/null
+++ b/sysdeps/sparc/sparc64/Implies
@@ -0,0 +1 @@
+wordsize-64
diff --git a/sysdeps/sparc/sparc64/Makefile b/sysdeps/sparc/sparc64/Makefile
new file mode 100644
index 0000000000..656274d75c
--- /dev/null
+++ b/sysdeps/sparc/sparc64/Makefile
@@ -0,0 +1,11 @@
+# The Sparc`long double' is a distinct type we support.
+#long-double-fcts = yes
+
+# But the support for ieee quads is so bad we just skip the whole thing.
+# XXX This is only a temporary hack.
+omit-long-double-fcts = yes
+
+# But we do need these few functions to even link stdio proggies
+ifeq ($(subdir),math)
+sysdep_routines += s_isinfl s_isnanl s_finitel s_signbitl
+endif
diff --git a/sysdeps/sparc/sparc64/add_n.S b/sysdeps/sparc/sparc64/add_n.S
new file mode 100644
index 0000000000..68bb008a7d
--- /dev/null
+++ b/sysdeps/sparc/sparc64/add_n.S
@@ -0,0 +1,58 @@
+/* SPARC v9 __mpn_add_n -- Add two limb vectors of the same length > 0 and
+ store sum in a third limb vector.
+
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+
+#include <sysdep.h>
+
+
+/* INPUT PARAMETERS
+ res_ptr %o0
+ s1_ptr %o1
+ s2_ptr %o2
+ size %o3 */
+
+
+ENTRY(__mpn_add_n)
+
+ sub %g0,%o3,%g3
+ sllx %o3,3,%g1
+ add %o1,%g1,%o1 ! make s1_ptr point at end
+ add %o2,%g1,%o2 ! make s2_ptr point at end
+ add %o0,%g1,%o0 ! make res_ptr point at end
+ mov 0,%o4 ! clear carry variable
+ sllx %g3,3,%o5 ! compute initial address index
+
+1: ldx [%o2+%o5],%g1 ! load s2 limb
+ add %g3,1,%g3 ! increment loop count
+ ldx [%o1+%o5],%g2 ! load s1 limb
+ addcc %g1,%o4,%g1 ! add s2 limb and carry variable
+ movcc %xcc,0,%o4 ! if carry-out, o4 was 1; clear it
+ addcc %g1,%g2,%g1 ! add s1 limb to sum
+ stx %g1,[%o0+%o5] ! store result
+ add %o5,8,%o5 ! increment address index
+ brnz,pt %g3,1b
+ movcs %xcc,1,%o4 ! if s1 add gave carry, record it
+
+ retl
+ mov %o4,%o0
+
+END(__mpn_add_n)
diff --git a/sysdeps/sparc/sparc64/add_n.s b/sysdeps/sparc/sparc64/add_n.s
deleted file mode 100644
index 01d1f49564..0000000000
--- a/sysdeps/sparc/sparc64/add_n.s
+++ /dev/null
@@ -1,58 +0,0 @@
-! SPARC v9 __mpn_add_n -- Add two limb vectors of the same length > 0 and store
-! sum in a third limb vector.
-
-! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-! This file is part of the GNU MP Library.
-
-! The GNU MP Library is free software; you can redistribute it and/or modify
-! it under the terms of the GNU Library General Public License as published by
-! the Free Software Foundation; either version 2 of the License, or (at your
-! option) any later version.
-
-! The GNU MP Library is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
-! License for more details.
-
-! You should have received a copy of the GNU Library General Public License
-! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
-! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-! MA 02111-1307, USA.
-
-
-! INPUT PARAMETERS
-! res_ptr %o0
-! s1_ptr %o1
-! s2_ptr %o2
-! size %o3
-
-.section ".text"
- .align 4
- .global __mpn_add_n
- .type __mpn_add_n,#function
- .proc 04
-__mpn_add_n:
- sub %g0,%o3,%g3
- sllx %o3,3,%g1
- add %o1,%g1,%o1 ! make s1_ptr point at end
- add %o2,%g1,%o2 ! make s2_ptr point at end
- add %o0,%g1,%o0 ! make res_ptr point at end
- mov 0,%o4 ! clear carry variable
- sllx %g3,3,%o5 ! compute initial address index
-
-.Loop: ldx [%o2+%o5],%g1 ! load s2 limb
- add %g3,1,%g3 ! increment loop count
- ldx [%o1+%o5],%g2 ! load s1 limb
- addcc %g1,%o4,%g1 ! add s2 limb and carry variable
- movcc %xcc,0,%o4 ! if carry-out, o4 was 1; clear it
- addcc %g1,%g2,%g1 ! add s1 limb to sum
- stx %g1,[%o0+%o5] ! store result
- add %o5,8,%o5 ! increment address index
- brnz,pt %g3,.Loop
- movcs %xcc,1,%o4 ! if s1 add gave carry, record it
-
- retl
- mov %o4,%o0
-.LLfe1:
- .size __mpn_add_n,.LLfe1-__mpn_add_n
diff --git a/sysdeps/sparc/sparc64/addmul_1.s b/sysdeps/sparc/sparc64/addmul_1.s
deleted file mode 100644
index 8d86390808..0000000000
--- a/sysdeps/sparc/sparc64/addmul_1.s
+++ /dev/null
@@ -1,89 +0,0 @@
-! SPARC v9 __mpn_addmul_1 -- Multiply a limb vector with a single limb and
-! add the product to a second limb vector.
-
-! Copyright (C) 1996 Free Software Foundation, Inc.
-
-! This file is part of the GNU MP Library.
-
-! The GNU MP Library is free software; you can redistribute it and/or modify
-! it under the terms of the GNU Library General Public License as published by
-! the Free Software Foundation; either version 2 of the License, or (at your
-! option) any later version.
-
-! The GNU MP Library is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
-! License for more details.
-
-! You should have received a copy of the GNU Library General Public License
-! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
-! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-! MA 02111-1307, USA.
-
-
-! INPUT PARAMETERS
-! res_ptr o0
-! s1_ptr o1
-! size o2
-! s2_limb o3
-
-.section ".text"
- .align 4
- .global __mpn_addmul_1
- .type __mpn_addmul_1,#function
- .proc 016
-__mpn_addmul_1:
- !#PROLOGUE# 0
- save %sp,-160,%sp
- !#PROLOGUE# 1
- sub %g0,%i2,%o7
- sllx %o7,3,%g5
- sub %i1,%g5,%o3
- sub %i0,%g5,%o4
- mov 0,%o0 ! zero cy_limb
-
- srl %i3,0,%o1 ! extract low 32 bits of s2_limb
- srlx %i3,32,%i3 ! extract high 32 bits of s2_limb
- mov 1,%o2
- sllx %o2,32,%o2 ! o2 = 0x100000000
-
- ! hi !
- ! mid-1 !
- ! mid-2 !
- ! lo !
-.Loop:
- sllx %o7,3,%g1
- ldx [%o3+%g1],%g5
- srl %g5,0,%i0 ! zero hi bits
- srlx %g5,32,%g5
- mulx %o1,%i0,%i4 ! lo product
- mulx %i3,%i0,%i1 ! mid-1 product
- mulx %o1,%g5,%l2 ! mid-2 product
- mulx %i3,%g5,%i5 ! hi product
- srlx %i4,32,%i0 ! extract high 32 bits of lo product...
- add %i1,%i0,%i1 ! ...and add it to the mid-1 product
- addcc %i1,%l2,%i1 ! add mid products
- mov 0,%l0 ! we need the carry from that add...
- movcs %xcc,%o2,%l0 ! ...compute it and...
- add %i5,%l0,%i5 ! ...add to bit 32 of the hi product
- sllx %i1,32,%i0 ! align low bits of mid product
- srl %i4,0,%g5 ! zero high 32 bits of lo product
- add %i0,%g5,%i0 ! combine into low 64 bits of result
- srlx %i1,32,%i1 ! extract high bits of mid product...
- add %i5,%i1,%i1 ! ...and add them to the high result
- addcc %i0,%o0,%i0 ! add cy_limb to low 64 bits of result
- mov 0,%g5
- movcs %xcc,1,%g5
- add %o7,1,%o7
- ldx [%o4+%g1],%l1
- addcc %l1,%i0,%i0
- movcs %xcc,1,%g5
- stx %i0,[%o4+%g1]
- brnz %o7,.Loop
- add %i1,%g5,%o0 ! compute new cy_limb
-
- mov %o0,%i0
- ret
- restore
-.LLfe1:
- .size __mpn_addmul_1,.LLfe1-__mpn_addmul_1
diff --git a/sysdeps/sparc/sparc64/bytesex.h b/sysdeps/sparc/sparc64/bytesex.h
new file mode 100644
index 0000000000..5e0b5e83e5
--- /dev/null
+++ b/sysdeps/sparc/sparc64/bytesex.h
@@ -0,0 +1,8 @@
+/* Sparc is big-endian, but v9 supports endian conversion on loads/stores
+ and GCC supports such a mode. Be prepared. */
+
+#ifdef __LITTLE_ENDIAN__
+# define __BYTE_ORDER __LITTLE_ENDIAN
+#else
+# define __BYTE_ORDER __BIG_ENDIAN
+#endif
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
new file mode 100644
index 0000000000..ae17f568a5
--- /dev/null
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -0,0 +1,339 @@
+/* Machine-dependent ELF dynamic relocation inline functions. Sparc64 version.
+ 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. */
+
+#define ELF_MACHINE_NAME "sparc64"
+
+#include <assert.h>
+#include <string.h>
+#include <link.h>
+#include <sys/param.h>
+#include <sysdep.h>
+
+
+/* Translate a processor-specific dynamic tag to the index into l_info. */
+#define DT_SPARC(x) (DT_SPARC_##x - DT_LOPROC + DT_NUM)
+
+/* Return nonzero iff E_MACHINE is compatible with the running host. */
+static inline int
+elf_machine_matches_host (Elf64_Half e_machine)
+{
+ return e_machine == EM_SPARC64;
+}
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+static inline Elf64_Addr
+elf_machine_dynamic (void)
+{
+ register Elf64_Addr elf_pic_register __asm__("%l7");
+ return *(Elf64_Addr *)elf_pic_register;
+}
+
+
+/* Return the run-time load address of the shared object. */
+static inline Elf64_Addr
+elf_machine_load_address (void)
+{
+ register Elf64_Addr elf_pic_register __asm__("%l7");
+ Elf64_Addr pc, la;
+
+ /* Utilize the fact that a local .got entry will be partially
+ initialized at startup awaiting its RELATIVE fixup. */
+
+ __asm("sethi %%hi(.Load_address), %1\n"
+ ".Load_address:\n\t"
+ "rd %%pc, %0\n\t"
+ "or %1, %%lo(.Load_address), %1\n\t"
+ : "=r"(pc), "=r"(la));
+
+ return pc - *(Elf64_Addr *)(elf_pic_register + la);
+}
+
+static inline void
+elf_machine_fixup_plt(struct link_map *map, const Elf64_Rela *reloc,
+ Elf64_Addr *reloc_addr, Elf64_Addr value)
+{
+ Elf64_Dyn *pltfmt = map->l_info[DT_SPARC(PLTFMT)];
+ switch (pltfmt ? pltfmt->d_un.d_val : 0)
+ {
+ case 1: /* .got.plt with absolute addresses */
+ *reloc_addr = value;
+ break;
+ case 2: /* .got.plt with got-relative addresses */
+ *reloc_addr = value - (map->l_info[DT_PLTGOT]->d_un.d_ptr + map->l_addr);
+ break;
+ default:
+ assert (! "unexpected .plt format type");
+ }
+}
+
+#ifdef RESOLVE
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+static inline void
+elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
+ const Elf64_Sym *sym)
+{
+ Elf64_Addr * const reloc_addr = (void *) (map->l_addr + reloc->r_offset);
+
+#ifndef RTLD_BOOTSTRAP
+ /* This is defined in rtld.c, but nowhere in the static libc.a; make the
+ reference weak so static programs can still link. This declaration
+ cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
+ because rtld.c contains the common defn for _dl_rtld_map, which is
+ incompatible with a weak decl in the same file. */
+ weak_extern (_dl_rtld_map);
+#endif
+
+ if (ELF64_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE)
+ {
+#ifndef RTLD_BOOTSTRAP
+ if (map != &_dl_rtld_map) /* Already done in rtld itself. */
+#endif
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ }
+ else
+ {
+ int r_info = ELF64_R_TYPE (reloc->r_info);
+ Elf64_Addr value;
+
+ value = RESOLVE (&sym, version, ELF64_R_TYPE (reloc->r_info));
+ if (sym)
+ value += sym->st_value;
+ value += reloc->r_addend; /* Assume copy relocs have zero addend. */
+
+ switch (ELF64_R_TYPE (reloc->r_info))
+ {
+#ifndef RTLD_BOOTSTRAP
+ case R_SPARC_COPY:
+ memcpy (reloc_addr, (void *) value, sym->st_size);
+ break;
+#endif
+
+ case R_SPARC_64:
+ case R_SPARC_GLOB_DAT:
+ *reloc_addr = value;
+ break;
+ case R_SPARC_8:
+ *(char *) reloc_addr = value;
+ break;
+ case R_SPARC_16:
+ *(short *) reloc_addr = value;
+ break;
+ case R_SPARC_DISP8:
+ *(char *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
+ break;
+ case R_SPARC_DISP16:
+ *(short *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
+ break;
+ case R_SPARC_DISP32:
+ *(unsigned int *)reloc_addr = (value - (Elf64_Addr) reloc_addr);
+ break;
+ case R_SPARC_LO10:
+ *(unsigned *)reloc_addr = (*(unsigned *)reloc_addr & ~0x3ff)
+ | (value & 0x3ff);
+ break;
+ case R_SPARC_WDISP30:
+ *(unsigned *)reloc_addr = ((*(unsigned *)reloc_addr & 0xc0000000)
+ | ((value - (Elf64_Addr) reloc_addr) >> 2));
+ break;
+ case R_SPARC_HI22:
+ *(unsigned *)reloc_addr = (*(unsigned *)reloc_addr & 0xffc00000)
+ | (value >> 10);
+ break;
+
+ case R_SPARC_JMP_SLOT:
+ elf_machine_fixup_plt(map, reloc, reloc_addr, value);
+ break;
+
+ case R_SPARC_NONE: /* Alright, Wilbur. */
+ break;
+ default:
+ assert (! "unexpected dynamic reloc type");
+ break;
+ }
+ }
+}
+
+static inline void
+elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc)
+{
+ switch (ELF64_R_TYPE (reloc->r_info))
+ {
+ case R_SPARC_NONE:
+ case R_SPARC_JMP_SLOT:
+ break;
+ default:
+ assert (! "unexpected PLT reloc type");
+ break;
+ }
+}
+
+#endif /* RESOLVE */
+
+/* The PLT uses Elf64_Rela relocs. */
+#define elf_machine_relplt elf_machine_rela
+
+/* 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_JMP_SLOT R_SPARC_JMP_SLOT
+
+/* The SPARC never uses Elf64_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)
+{
+ Elf64_Addr *got;
+ extern void _dl_runtime_resolve (void);
+
+ if (l->l_info[DT_JMPREL] && lazy)
+ {
+ got = (Elf64_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
+ /* This function will get called to fix up the GOT entry indicated by
+ the offset on the stack, and then jump to the resolved address. */
+ got[1] = (Elf64_Addr) &_dl_runtime_resolve;
+ got[2] = (Elf64_Addr) l; /* Identify this shared object. */
+ }
+
+ 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:
+ save %sp, -160, %sp
+ mov %g1, %o0
+ call fixup
+ mov %g2, %o1
+ jmp %o0
+ restore
+ .size _dl_runtime_resolve, .-_dl_runtime_resolve
+");
+
+/* 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 __S1(x) #x
+#define __S(x) __S1(x)
+
+#define RTLD_START __asm__ ( "\
+ .global _start
+ .type _start, @function
+_start:
+ /* Make room for functions to drop their arguments on the stack. */
+ sub %sp, 6*8, %sp
+ /* Pass pointer to argument block to _dl_start. */
+ call _dl_start
+ add %sp," __S(STACK_BIAS) "+22*8,%o0
+ /* FALLTHRU */
+ .size _start, .-_start
+
+ .global _dl_start_user
+ .type _dl_start_user, @function
+_dl_start_user:
+ /* Load the GOT register. */
+1: call 11f
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)),%l7
+11: 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, we must shift things around since we
+ must keep the stack doubleword aligned. */
+ sethi %hi(_dl_skip_args), %g2
+ or %g2, %lo(_dl_skip_args), %g2
+ ldx [%l7+%g2], %i0
+ ld [%i0], %i0
+ brz,pt %i0, 2f
+ nop
+ /* Find out how far to shift. */
+ ldx [%sp+" __S(STACK_BIAS) "+22*8], %i1
+ sub %i1, %i0, %i1
+ sllx %i0, 3, %i2
+ stx %i1, [%sp+" __S(STACK_BIAS) "+22*8]
+ add %sp, " __S(STACK_BIAS) "+23*8, %i1
+ add %i1, %i2, %i2
+ /* Copy down argv. */
+12: ldx [%i2], %i3
+ add %i2, 8, %i2
+ stx %i3, [%i1]
+ brnz,pt %i3, 12b
+ add %i1, 8, %i1
+ /* Copy down envp. */
+13: ldx [%i2], %i3
+ add %i2, 8, %i2
+ stx %i3, [%i1]
+ brnz,pt %i3, 13b
+ add %i1, 8, %i1
+ /* Copy down auxiliary table. */
+14: ldx [%i2], %i3
+ ldx [%i2+8], %i4
+ add %i2, 16, %i2
+ stx %i3, [%i1]
+ stx %i4, [%i1+8]
+ brnz,pt %i3, 13b
+ add %i1, 16, %i1
+ /* Load _dl_default_scope[2] to pass to _dl_init_next. */
+2: sethi %hi(_dl_default_scope), %g2
+ or %g2, %lo(_dl_default_scope), %g2
+ ldx [%l7+%g2], %g2
+ ldx [%g2+2*8], %l1
+ /* Call _dl_init_next to return the address of an initializer to run. */
+3: call _dl_init_next
+ mov %l1, %o0
+ brz,pn %o0, 4f
+ nop
+ jmpl %o0, %o7
+ nop
+ ba,a 3b
+ /* Clear the startup flag. */
+4: sethi %hi(_dl_starting_up), %g2
+ or %g2, %lo(_dl_starting_up), %g2
+ ldx [%l7+%g2], %g2
+ st %g0, [%g2]
+ /* Pass our finalizer function to the user in %g1. */
+ sethi %hi(_dl_fini), %g1
+ or %g1, %lo(_dl_fini), %g1
+ ldx [%l7+%g1], %g1
+ /* Jump to the user's entry point & undo the allocation of the xtra regs. */
+ jmp %l0
+ add %sp, 6*8, %sp
+ .size _dl_start_user, .-_dl_start_user");
diff --git a/sysdeps/sparc/sparc64/elf/Dist b/sysdeps/sparc/sparc64/elf/Dist
new file mode 100644
index 0000000000..d9338c8fd6
--- /dev/null
+++ b/sysdeps/sparc/sparc64/elf/Dist
@@ -0,0 +1,4 @@
+crtbegin.S
+crtbeginS.S
+crtend.S
+crtendS.S
diff --git a/sysdeps/sparc/sparc64/elf/Makefile b/sysdeps/sparc/sparc64/elf/Makefile
new file mode 100644
index 0000000000..1b38355b38
--- /dev/null
+++ b/sysdeps/sparc/sparc64/elf/Makefile
@@ -0,0 +1,10 @@
+# The assembler on SPARC needs the -fPIC flag even when it's assembler code.
+ASFLAGS-.so = -fPIC
+
+ifeq ($(subdir), csu)
+extra-objs += crtbegin.o crtend.o crtbeginS.o crtendS.o
+install-lib += crtbegin.o crtend.o crtbeginS.o crtendS.o
+
+CPPFLAGS-crtbeginS.S = -fPIC -DPIC
+CPPFLAGS-crtendS.S = -fPIC -DPIC
+endif
diff --git a/sysdeps/sparc/sparc64/elf/crtbegin.S b/sysdeps/sparc/sparc64/elf/crtbegin.S
new file mode 100644
index 0000000000..318e7a6a3f
--- /dev/null
+++ b/sysdeps/sparc/sparc64/elf/crtbegin.S
@@ -0,0 +1,69 @@
+/* Destructor cleanup code for elf64-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. */
+
+
+.section ".ctors",#alloc,#write
+
+ .align 8
+__CTOR_LIST__:
+ .xword -1
+
+.section ".dtors",#alloc,#write
+
+ .align 8
+__DTOR_LIST__:
+ .xword -1
+
+.section ".fini",#alloc,#execinstr
+
+ call __do_global_dtors_aux
+ nop
+
+.text
+
+ .align 4
+ .type __do_global_dtors_aux,#function
+__do_global_dtors_aux:
+ save %sp,-160,%sp
+
+#ifdef PIC
+1: call 11f
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+11: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+ add %l7, %o7, %l7
+ sethi %hi(__DTOR_LIST__), %l0
+ or %l0, %lo(__DTOR_LIST__), %l0
+ ldx [%l7+%l0], %l0
+#else
+ sethi %hi(__DTOR_LIST__), %l0
+ or %l0, %lo(__DTOR_LIST__), %l0
+ add %l0, %g4, %l0
+#endif
+
+ ba 3f
+ ldx [%l0+8], %l1
+2: jmpl %l1, %o7
+ ldx [%l0+8], %l1
+3: brnz,pt %l1, 2b
+ add %l0, 8, %l0
+
+ ret
+ restore
+
+ .size __do_global_dtors_aux,.-__do_global_dtors_aux
diff --git a/sysdeps/sparc/sparc64/elf/crtbeginS.S b/sysdeps/sparc/sparc64/elf/crtbeginS.S
new file mode 100644
index 0000000000..7db4bc590e
--- /dev/null
+++ b/sysdeps/sparc/sparc64/elf/crtbeginS.S
@@ -0,0 +1 @@
+#include "crtbegin.S"
diff --git a/sysdeps/sparc/sparc64/elf/crtend.S b/sysdeps/sparc/sparc64/elf/crtend.S
new file mode 100644
index 0000000000..7a5c067b07
--- /dev/null
+++ b/sysdeps/sparc/sparc64/elf/crtend.S
@@ -0,0 +1,70 @@
+/* Constructor startup code for elf64-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. */
+
+
+.section ".ctors",#alloc,#write
+
+ .align 8
+__CTOR_END__:
+ .xword 0
+
+.section ".dtors",#alloc,#write
+
+ .align 8
+__DTOR_END__:
+ .xword 0
+
+.section ".init",#alloc,#execinstr
+
+ call __do_global_ctors_aux
+ nop
+
+.text
+
+ .align 4
+ .type __do_global_ctors_aux,#function
+__do_global_ctors_aux:
+ save %sp,-160,%sp
+
+#ifdef PIC
+1: call 11f
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+11: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+ add %l7, %o7, %l7
+ sethi %hi(__CTOR_END__), %l0
+ or %l0, %lo(__CTOR_END__), %l0
+ ldx [%l7+%l0], %l0
+#else
+ sethi %hi(__CTOR_END__), %l0
+ or %l0, %lo(__CTOR_END__), %l0
+ add %l0, %g4, %l0
+#endif
+
+ ba 3f
+ ldx [%l0+8], %l1
+2: jmpl %l1, %o7
+ ldx [%l0+8], %l1
+3: addcc %l1, 1, %g0
+ bnz,pt %xcc, 2b
+ add %l0, 8, %l0
+
+ ret
+ restore
+
+ .size __do_global_ctors_aux,.-__do_global_ctors_aux
diff --git a/sysdeps/sparc/sparc64/elf/crtendS.S b/sysdeps/sparc/sparc64/elf/crtendS.S
new file mode 100644
index 0000000000..56532f567d
--- /dev/null
+++ b/sysdeps/sparc/sparc64/elf/crtendS.S
@@ -0,0 +1 @@
+#include "crtend.S"
diff --git a/sysdeps/sparc/sparc64/elf/start.S b/sysdeps/sparc/sparc64/elf/start.S
new file mode 100644
index 0000000000..73f42367ee
--- /dev/null
+++ b/sysdeps/sparc/sparc64/elf/start.S
@@ -0,0 +1,93 @@
+/* Startup code for elf64-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:
+
+ /* First order of business is to load %g4 with our base address. */
+ sethi %uhi(_start), %g4
+ or %g4, %ulo(_start), %g4
+ sllx %g4, 32, %g4
+
+ /* Terminate the stack frame, and reserve space for functions to
+ drop their arguments. */
+ mov %g0, %fp
+ sub %sp, 6*8, %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: */
+
+ brz,pn %l0, 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,
+ plus the bias we added, plus the magic v9 STACK_BIAS. */
+ ldx [%sp+STACK_BIAS+22*8], %o0
+ add %sp, STACK_BIAS+23*8, %o1
+ sllx %o0, 3, %o2
+ add %o2, %o1, %o2
+ sethi %hi(__environ), %g2
+ add %o2, 8, %o2
+ add %g2, %g4, %g2
+ stx %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
+ add %o0, %g4, %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. */
+ illtrap 0
+
+ .size _start,.-_start
diff --git a/sysdeps/sparc/sparc64/fpu/fpu_control.h b/sysdeps/sparc/sparc64/fpu/fpu_control.h
new file mode 100644
index 0000000000..bedc034eaa
--- /dev/null
+++ b/sysdeps/sparc/sparc64/fpu/fpu_control.h
@@ -0,0 +1,67 @@
+/* FPU control word bits. SPARC v9 version.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza
+
+ 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. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H 1
+
+
+#include <features.h>
+
+/* precision control */
+#define _FPU_EXTENDED 0x00000000 /* RECOMMENDED */
+#define _FPU_DOUBLE 0x20000000
+#define _FPU_80BIT 0x30000000
+#define _FPU_SINGLE 0x10000000 /* DO NOT USE */
+
+/* rounding control / Sparc */
+#define _FPU_RC_DOWN 0xc0000000
+#define _FPU_RC_UP 0x80000000
+#define _FPU_RC_ZERO 0x40000000
+#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
+
+#define _FPU_RESERVED 0x30300000 /* Reserved bits in cw */
+
+
+/* Now two recommended cw */
+
+/* Linux and IEEE default:
+ - extended precision
+ - rounding to nearest
+ - no exceptions */
+#define _FPU_DEFAULT 0x0
+#define _FPU_IEEE 0x0
+
+/* Type of the control word. */
+typedef unsigned long fpu_control_t;
+
+#define _FPU_GETCW(cw) __asm__ ("stx %%fsr,%0" : "=m" (*&cw))
+#define _FPU_SETCW(cw) __asm__ ("ldx %0,%%fsr" : : "m" (*&cw))
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+__BEGIN_DECLS
+
+/* Called at startup. It can be used to manipulate fpu control register. */
+extern void __setfpucw __P ((fpu_control_t));
+
+__END_DECLS
+
+#endif /* fpu_control.h */
diff --git a/sysdeps/sparc/sparc64/lshift.S b/sysdeps/sparc/sparc64/lshift.S
new file mode 100644
index 0000000000..1678991529
--- /dev/null
+++ b/sysdeps/sparc/sparc64/lshift.S
@@ -0,0 +1,96 @@
+/* SPARC v9 __mpn_lshift --
+
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+/* INPUT PARAMETERS
+ res_ptr %i0
+ src_ptr %i1
+ size %i2
+ cnt %i3 */
+
+ENTRY(__mpn_lshift)
+ save %sp, -128, %sp
+
+ sllx %i2,3,%g1
+ add %i1,%g1,%i1 ! make %i1 point at end of src
+ ldx [%i1-8],%g2 ! load first limb
+ sub %g0,%i3,%i5 ! negate shift count
+ add %i0,%g1,%i0 ! make %i0 point at end of res
+ add %i2,-1,%i2
+ and %i2,4-1,%l4 ! number of limbs in first loop
+ srlx %g2,%i5,%g1 ! compute function result
+ brz,pn %l4,.L0 ! if multiple of 4 limbs, skip first loop
+ mov %g1,%l1
+
+ sub %i2,%l4,%i2 ! adjust count for main loop
+
+.Loop0: ldx [%i1-16],%g3
+ add %i0,-8,%i0
+ add %i1,-8,%i1
+ add %l4,-1,%l4
+ sllx %g2,%i3,%i4
+ srlx %g3,%i5,%g1
+ mov %g3,%g2
+ or %i4,%g1,%i4
+ brnz,pt %l4,.Loop0
+ stx %i4,[%i0+0]
+
+.L0: brz,pn %i2,.Lend
+ nop
+
+.Loop: ldx [%i1-16],%g3
+ add %i0,-32,%i0
+ add %i2,-4,%i2
+ sllx %g2,%i3,%i4
+ srlx %g3,%i5,%g1
+
+ ldx [%i1-24],%g2
+ sllx %g3,%i3,%l4
+ or %i4,%g1,%i4
+ stx %i4,[%i0+24]
+ srlx %g2,%i5,%g1
+
+ ldx [%i1-32],%g3
+ sllx %g2,%i3,%i4
+ or %l4,%g1,%l4
+ stx %l4,[%i0+16]
+ srlx %g3,%i5,%g1
+
+ ldx [%i1-40],%g2
+ sllx %g3,%i3,%l4
+ or %i4,%g1,%i4
+ stx %i4,[%i0+8]
+ srlx %g2,%i5,%g1
+
+ add %i1,-32,%i1
+ or %l4,%g1,%l4
+ brnz,pt %i2,.Loop
+ stx %l4,[%i0+0]
+
+.Lend: sllx %g2,%i3,%g2
+ stx %g2,[%i0-8]
+
+ mov %l1,%i0
+ jmpl %i7+8, %g0
+ restore
+
+END(__mpn_lshift)
diff --git a/sysdeps/sparc/sparc64/lshift.s b/sysdeps/sparc/sparc64/lshift.s
deleted file mode 100644
index ad1f667fa3..0000000000
--- a/sysdeps/sparc/sparc64/lshift.s
+++ /dev/null
@@ -1,96 +0,0 @@
-! SPARC v9 __mpn_lshift --
-
-! Copyright (C) 1996 Free Software Foundation, Inc.
-
-! This file is part of the GNU MP Library.
-
-! The GNU MP Library is free software; you can redistribute it and/or modify
-! it under the terms of the GNU Library General Public License as published by
-! the Free Software Foundation; either version 2 of the License, or (at your
-! option) any later version.
-
-! The GNU MP Library is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
-! License for more details.
-
-! You should have received a copy of the GNU Library General Public License
-! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
-! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-! MA 02111-1307, USA.
-
-
-! INPUT PARAMETERS
-! res_ptr %o0
-! src_ptr %o1
-! size %o2
-! cnt %o3
-
-.section ".text"
- .align 4
- .global __mpn_lshift
- .type __mpn_lshift,#function
- .proc 04
-__mpn_lshift:
- sllx %o2,3,%g1
- add %o1,%g1,%o1 ! make %o1 point at end of src
- ldx [%o1-8],%g2 ! load first limb
- sub %g0,%o3,%o5 ! negate shift count
- add %o0,%g1,%o0 ! make %o0 point at end of res
- add %o2,-1,%o2
- and %o2,4-1,%g4 ! number of limbs in first loop
- srlx %g2,%o5,%g1 ! compute function result
- brz,pn %g4,.L0 ! if multiple of 4 limbs, skip first loop
- stx %g1,[%sp+80]
-
- sub %o2,%g4,%o2 ! adjust count for main loop
-
-.Loop0: ldx [%o1-16],%g3
- add %o0,-8,%o0
- add %o1,-8,%o1
- add %g4,-1,%g4
- sllx %g2,%o3,%o4
- srlx %g3,%o5,%g1
- mov %g3,%g2
- or %o4,%g1,%o4
- brnz,pt %g4,.Loop0
- stx %o4,[%o0+0]
-
-.L0: brz,pn %o2,.Lend
- nop
-
-.Loop: ldx [%o1-16],%g3
- add %o0,-32,%o0
- add %o2,-4,%o2
- sllx %g2,%o3,%o4
- srlx %g3,%o5,%g1
-
- ldx [%o1-24],%g2
- sllx %g3,%o3,%g4
- or %o4,%g1,%o4
- stx %o4,[%o0+24]
- srlx %g2,%o5,%g1
-
- ldx [%o1-32],%g3
- sllx %g2,%o3,%o4
- or %g4,%g1,%g4
- stx %g4,[%o0+16]
- srlx %g3,%o5,%g1
-
- ldx [%o1-40],%g2
- sllx %g3,%o3,%g4
- or %o4,%g1,%o4
- stx %o4,[%o0+8]
- srlx %g2,%o5,%g1
-
- add %o1,-32,%o1
- or %g4,%g1,%g4
- brnz,pt %o2,.Loop
- stx %g4,[%o0+0]
-
-.Lend: sllx %g2,%o3,%g2
- stx %g2,[%o0-8]
- retl
- ldx [%sp+80],%o0
-.LLfe1:
- .size __mpn_lshift,.LLfe1-__mpn_lshift
diff --git a/sysdeps/sparc/sparc64/mul_1.s b/sysdeps/sparc/sparc64/mul_1.s
deleted file mode 100644
index 91d6eb01b8..0000000000
--- a/sysdeps/sparc/sparc64/mul_1.s
+++ /dev/null
@@ -1,86 +0,0 @@
-! SPARC v9 __mpn_mul_1 -- Multiply a limb vector with a single limb and
-! store the product in a second limb vector.
-
-! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-! This file is part of the GNU MP Library.
-
-! The GNU MP Library is free software; you can redistribute it and/or modify
-! it under the terms of the GNU Library General Public License as published by
-! the Free Software Foundation; either version 2 of the License, or (at your
-! option) any later version.
-
-! The GNU MP Library is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
-! License for more details.
-
-! You should have received a copy of the GNU Library General Public License
-! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
-! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-! MA 02111-1307, USA.
-
-
-! INPUT PARAMETERS
-! res_ptr o0
-! s1_ptr o1
-! size o2
-! s2_limb o3
-
-.section ".text"
- .align 4
- .global __mpn_mul_1
- .type __mpn_mul_1,#function
- .proc 016
-__mpn_mul_1:
- !#PROLOGUE# 0
- save %sp,-160,%sp
- !#PROLOGUE# 1
- sub %g0,%i2,%o7
- sllx %o7,3,%g5
- sub %i1,%g5,%o3
- sub %i0,%g5,%o4
- mov 0,%o0 ! zero cy_limb
-
- srl %i3,0,%o1 ! extract low 32 bits of s2_limb
- srlx %i3,32,%i3 ! extract high 32 bits of s2_limb
- mov 1,%o2
- sllx %o2,32,%o2 ! o2 = 0x100000000
-
- ! hi !
- ! mid-1 !
- ! mid-2 !
- ! lo !
-.Loop:
- sllx %o7,3,%g1
- ldx [%o3+%g1],%g5
- srl %g5,0,%i0 ! zero hi bits
- srlx %g5,32,%g5
- mulx %o1,%i0,%i4 ! lo product
- mulx %i3,%i0,%i1 ! mid-1 product
- mulx %o1,%g5,%l2 ! mid-2 product
- mulx %i3,%g5,%i5 ! hi product
- srlx %i4,32,%i0 ! extract high 32 bits of lo product...
- add %i1,%i0,%i1 ! ...and add it to the mid-1 product
- addcc %i1,%l2,%i1 ! add mid products
- mov 0,%l0 ! we need the carry from that add...
- movcs %xcc,%o2,%l0 ! ...compute it and...
- add %i5,%l0,%i5 ! ...add to bit 32 of the hi product
- sllx %i1,32,%i0 ! align low bits of mid product
- srl %i4,0,%g5 ! zero high 32 bits of lo product
- add %i0,%g5,%i0 ! combine into low 64 bits of result
- srlx %i1,32,%i1 ! extract high bits of mid product...
- add %i5,%i1,%i1 ! ...and add them to the high result
- addcc %i0,%o0,%i0 ! add cy_limb to low 64 bits of result
- mov 0,%g5
- movcs %xcc,1,%g5
- add %o7,1,%o7
- stx %i0,[%o4+%g1]
- brnz %o7,.Loop
- add %i1,%g5,%o0 ! compute new cy_limb
-
- mov %o0,%i0
- ret
- restore
-.LLfe1:
- .size __mpn_mul_1,.LLfe1-__mpn_mul_1
diff --git a/sysdeps/sparc/sparc64/rshift.S b/sysdeps/sparc/sparc64/rshift.S
new file mode 100644
index 0000000000..e1b3aca112
--- /dev/null
+++ b/sysdeps/sparc/sparc64/rshift.S
@@ -0,0 +1,93 @@
+/* SPARC v9 __mpn_rshift --
+
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+/* INPUT PARAMETERS
+ res_ptr %i0
+ src_ptr %i1
+ size %i2
+ cnt %i3 */
+
+ENTRY(__mpn_rshift)
+ save %sp, -128, %sp
+
+ ldx [%i1],%g2 ! load first limb
+ sub %g0,%i3,%i5 ! negate shift count
+ add %i2,-1,%i2
+ and %i2,4-1,%l4 ! number of limbs in first loop
+ sllx %g2,%i5,%g1 ! compute function result
+ brz,pn %l4,.L0 ! if multiple of 4 limbs, skip first loop
+ mov %g1,%l1
+
+ sub %i2,%l4,%i2 ! adjust count for main loop
+
+.Loop0: ldx [%i1+8],%g3
+ add %i0,8,%i0
+ add %i1,8,%i1
+ add %l4,-1,%l4
+ srlx %g2,%i3,%i4
+ sllx %g3,%i5,%g1
+ mov %g3,%g2
+ or %i4,%g1,%i4
+ brnz,pt %l4,.Loop0
+ stx %i4,[%i0-8]
+
+.L0: brz,pn %i2,.Lend
+ nop
+
+.Loop: ldx [%i1+8],%g3
+ add %i0,32,%i0
+ add %i2,-4,%i2
+ srlx %g2,%i3,%i4
+ sllx %g3,%i5,%g1
+
+ ldx [%i1+16],%g2
+ srlx %g3,%i3,%l4
+ or %i4,%g1,%i4
+ stx %i4,[%i0-32]
+ sllx %g2,%i5,%g1
+
+ ldx [%i1+24],%g3
+ srlx %g2,%i3,%i4
+ or %l4,%g1,%l4
+ stx %l4,[%i0-24]
+ sllx %g3,%i5,%g1
+
+ ldx [%i1+32],%g2
+ srlx %g3,%i3,%l4
+ or %i4,%g1,%i4
+ stx %i4,[%i0-16]
+ sllx %g2,%i5,%g1
+
+ add %i1,32,%i1
+ or %l4,%g1,%l4
+ brnz %i2,.Loop
+ stx %l4,[%i0-8]
+
+.Lend: srlx %g2,%i3,%g2
+ stx %g2,[%i0-0]
+
+ mov %l1,%i0
+ jmpl %i7+8,%g0
+ restore
+
+END(__mpn_rshift)
diff --git a/sysdeps/sparc/sparc64/rshift.s b/sysdeps/sparc/sparc64/rshift.s
deleted file mode 100644
index ff6a380160..0000000000
--- a/sysdeps/sparc/sparc64/rshift.s
+++ /dev/null
@@ -1,93 +0,0 @@
-! SPARC v9 __mpn_rshift --
-
-! Copyright (C) 1996 Free Software Foundation, Inc.
-
-! This file is part of the GNU MP Library.
-
-! The GNU MP Library is free software; you can redistribute it and/or modify
-! it under the terms of the GNU Library General Public License as published by
-! the Free Software Foundation; either version 2 of the License, or (at your
-! option) any later version.
-
-! The GNU MP Library is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
-! License for more details.
-
-! You should have received a copy of the GNU Library General Public License
-! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
-! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-! MA 02111-1307, USA.
-
-
-! INPUT PARAMETERS
-! res_ptr %o0
-! src_ptr %o1
-! size %o2
-! cnt %o3
-
-.section ".text"
- .align 4
- .global __mpn_rshift
- .type __mpn_rshift,#function
- .proc 04
-__mpn_rshift:
- ldx [%o1],%g2 ! load first limb
- sub %g0,%o3,%o5 ! negate shift count
- add %o2,-1,%o2
- and %o2,4-1,%g4 ! number of limbs in first loop
- sllx %g2,%o5,%g1 ! compute function result
- brz,pn %g4,.L0 ! if multiple of 4 limbs, skip first loop
- stx %g1,[%sp+80]
-
- sub %o2,%g4,%o2 ! adjust count for main loop
-
-.Loop0: ldx [%o1+8],%g3
- add %o0,8,%o0
- add %o1,8,%o1
- add %g4,-1,%g4
- srlx %g2,%o3,%o4
- sllx %g3,%o5,%g1
- mov %g3,%g2
- or %o4,%g1,%o4
- brnz,pt %g4,.Loop0
- stx %o4,[%o0-8]
-
-.L0: brz,pn %o2,.Lend
- nop
-
-.Loop: ldx [%o1+8],%g3
- add %o0,32,%o0
- add %o2,-4,%o2
- srlx %g2,%o3,%o4
- sllx %g3,%o5,%g1
-
- ldx [%o1+16],%g2
- srlx %g3,%o3,%g4
- or %o4,%g1,%o4
- stx %o4,[%o0-32]
- sllx %g2,%o5,%g1
-
- ldx [%o1+24],%g3
- srlx %g2,%o3,%o4
- or %g4,%g1,%g4
- stx %g4,[%o0-24]
- sllx %g3,%o5,%g1
-
- ldx [%o1+32],%g2
- srlx %g3,%o3,%g4
- or %o4,%g1,%o4
- stx %o4,[%o0-16]
- sllx %g2,%o5,%g1
-
- add %o1,32,%o1
- or %g4,%g1,%g4
- brnz %o2,.Loop
- stx %g4,[%o0-8]
-
-.Lend: srlx %g2,%o3,%g2
- stx %g2,[%o0-0]
- retl
- ldx [%sp+80],%o0
-.LLfe1:
- .size __mpn_rshift,.LLfe1-__mpn_rshift
diff --git a/sysdeps/sparc/sparc64/sub_n.S b/sysdeps/sparc/sparc64/sub_n.S
new file mode 100644
index 0000000000..403d50c704
--- /dev/null
+++ b/sysdeps/sparc/sparc64/sub_n.S
@@ -0,0 +1,55 @@
+/* SPARC v9 __mpn_sub_n -- Subtract two limb vectors of the same length > 0
+ and store difference in a third limb vector.
+
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+/* INPUT PARAMETERS
+ res_ptr %o0
+ s1_ptr %o1
+ s2_ptr %o2
+ size %o3 */
+
+ENTRY(__mpn_sub_n)
+
+ sub %g0,%o3,%g3
+ sllx %o3,3,%g1
+ add %o1,%g1,%o1 ! make s1_ptr point at end
+ add %o2,%g1,%o2 ! make s2_ptr point at end
+ add %o0,%g1,%o0 ! make res_ptr point at end
+ mov 0,%o4 ! clear carry variable
+ sllx %g3,3,%o5 ! compute initial address index
+
+1: ldx [%o2+%o5],%g1 ! load s2 limb
+ add %g3,1,%g3 ! increment loop count
+ ldx [%o1+%o5],%g2 ! load s1 limb
+ addcc %g1,%o4,%g1 ! add s2 limb and carry variable
+ movcc %xcc,0,%o4 ! if carry-out, o4 was 1; clear it
+ subcc %g2,%g1,%g1 ! subtract s1 limb from sum
+ stx %g1,[%o0+%o5] ! store result
+ add %o5,8,%o5 ! increment address index
+ brnz,pt %g3,1b
+ movcs %xcc,1,%o4 ! if s1 subtract gave carry, record it
+
+ retl
+ mov %o4,%o0
+
+END(__mpn_sub_n)
diff --git a/sysdeps/sparc/sparc64/sub_n.s b/sysdeps/sparc/sparc64/sub_n.s
deleted file mode 100644
index d4842b8cdd..0000000000
--- a/sysdeps/sparc/sparc64/sub_n.s
+++ /dev/null
@@ -1,58 +0,0 @@
-! SPARC v9 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
-! store difference in a third limb vector.
-
-! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-! This file is part of the GNU MP Library.
-
-! The GNU MP Library is free software; you can redistribute it and/or modify
-! it under the terms of the GNU Library General Public License as published by
-! the Free Software Foundation; either version 2 of the License, or (at your
-! option) any later version.
-
-! The GNU MP Library is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
-! License for more details.
-
-! You should have received a copy of the GNU Library General Public License
-! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
-! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-! MA 02111-1307, USA.
-
-
-! INPUT PARAMETERS
-! res_ptr %o0
-! s1_ptr %o1
-! s2_ptr %o2
-! size %o3
-
-.section ".text"
- .align 4
- .global __mpn_sub_n
- .type __mpn_sub_n,#function
- .proc 04
-__mpn_sub_n:
- sub %g0,%o3,%g3
- sllx %o3,3,%g1
- add %o1,%g1,%o1 ! make s1_ptr point at end
- add %o2,%g1,%o2 ! make s2_ptr point at end
- add %o0,%g1,%o0 ! make res_ptr point at end
- mov 0,%o4 ! clear carry variable
- sllx %g3,3,%o5 ! compute initial address index
-
-.Loop: ldx [%o2+%o5],%g1 ! load s2 limb
- add %g3,1,%g3 ! increment loop count
- ldx [%o1+%o5],%g2 ! load s1 limb
- addcc %g1,%o4,%g1 ! add s2 limb and carry variable
- movcc %xcc,0,%o4 ! if carry-out, o4 was 1; clear it
- subcc %g1,%g2,%g1 ! subtract s1 limb from sum
- stx %g1,[%o0+%o5] ! store result
- add %o5,8,%o5 ! increment address index
- brnz,pt %g3,.Loop
- movcs %xcc,1,%o4 ! if s1 subtract gave carry, record it
-
- retl
- mov %o4,%o0
-.LLfe1:
- .size __mpn_sub_n,.LLfe1-__mpn_sub_n
diff --git a/sysdeps/sparc/sparc64/submul_1.s b/sysdeps/sparc/sparc64/submul_1.s
deleted file mode 100644
index e796243470..0000000000
--- a/sysdeps/sparc/sparc64/submul_1.s
+++ /dev/null
@@ -1,89 +0,0 @@
-! SPARC v9 __mpn_submul_1 -- Multiply a limb vector with a single limb and
-! subtract the product from a second limb vector.
-
-! Copyright (C) 1996 Free Software Foundation, Inc.
-
-! This file is part of the GNU MP Library.
-
-! The GNU MP Library is free software; you can redistribute it and/or modify
-! it under the terms of the GNU Library General Public License as published by
-! the Free Software Foundation; either version 2 of the License, or (at your
-! option) any later version.
-
-! The GNU MP Library is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
-! License for more details.
-
-! You should have received a copy of the GNU Library General Public License
-! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
-! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-! MA 02111-1307, USA.
-
-
-! INPUT PARAMETERS
-! res_ptr o0
-! s1_ptr o1
-! size o2
-! s2_limb o3
-
-.section ".text"
- .align 4
- .global __mpn_submul_1
- .type __mpn_submul_1,#function
- .proc 016
-__mpn_submul_1:
- !#PROLOGUE# 0
- save %sp,-160,%sp
- !#PROLOGUE# 1
- sub %g0,%i2,%o7
- sllx %o7,3,%g5
- sub %i1,%g5,%o3
- sub %i0,%g5,%o4
- mov 0,%o0 ! zero cy_limb
-
- srl %i3,0,%o1 ! extract low 32 bits of s2_limb
- srlx %i3,32,%i3 ! extract high 32 bits of s2_limb
- mov 1,%o2
- sllx %o2,32,%o2 ! o2 = 0x100000000
-
- ! hi !
- ! mid-1 !
- ! mid-2 !
- ! lo !
-.Loop:
- sllx %o7,3,%g1
- ldx [%o3+%g1],%g5
- srl %g5,0,%i0 ! zero hi bits
- srlx %g5,32,%g5
- mulx %o1,%i0,%i4 ! lo product
- mulx %i3,%i0,%i1 ! mid-1 product
- mulx %o1,%g5,%l2 ! mid-2 product
- mulx %i3,%g5,%i5 ! hi product
- srlx %i4,32,%i0 ! extract high 32 bits of lo product...
- add %i1,%i0,%i1 ! ...and add it to the mid-1 product
- addcc %i1,%l2,%i1 ! add mid products
- mov 0,%l0 ! we need the carry from that add...
- movcs %xcc,%o2,%l0 ! ...compute it and...
- add %i5,%l0,%i5 ! ...add to bit 32 of the hi product
- sllx %i1,32,%i0 ! align low bits of mid product
- srl %i4,0,%g5 ! zero high 32 bits of lo product
- add %i0,%g5,%i0 ! combine into low 64 bits of result
- srlx %i1,32,%i1 ! extract high bits of mid product...
- add %i5,%i1,%i1 ! ...and add them to the high result
- addcc %i0,%o0,%i0 ! add cy_limb to low 64 bits of result
- mov 0,%g5
- movcs %xcc,1,%g5
- add %o7,1,%o7
- ldx [%o4+%g1],%l1
- subcc %l1,%i0,%i0
- movcs %xcc,1,%g5
- stx %i0,[%o4+%g1]
- brnz %o7,.Loop
- add %i1,%g5,%o0 ! compute new cy_limb
-
- mov %o0,%i0
- ret
- restore
-.LLfe1:
- .size __mpn_submul_1,.LLfe1-__mpn_submul_1
diff --git a/sysdeps/sparc/sub_n.S b/sysdeps/sparc/sub_n.S
deleted file mode 100644
index b7a11958e2..0000000000
--- a/sysdeps/sparc/sub_n.S
+++ /dev/null
@@ -1,311 +0,0 @@
-! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
-! store difference in a third limb vector.
-
-! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-! This file is part of the GNU MP Library.
-
-! The GNU MP Library is free software; you can redistribute it and/or modify
-! it under the terms of the GNU Library General Public License as published by
-! the Free Software Foundation; either version 2 of the License, or (at your
-! option) any later version.
-
-! The GNU MP Library is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
-! License for more details.
-
-! You should have received a copy of the GNU Library General Public License
-! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
-! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-! MA 02111-1307, USA.
-
-
-! INPUT PARAMETERS
-#define res_ptr %o0
-#define s1_ptr %o1
-#define s2_ptr %o2
-#define size %o3
-
-#include "sysdep.h"
-
- .text
- .align 4
- .global C_SYMBOL_NAME(__mpn_sub_n)
-C_SYMBOL_NAME(__mpn_sub_n):
- xor s2_ptr,res_ptr,%g1
- andcc %g1,4,%g0
- bne L1 ! branch if alignment differs
- nop
-! ** V1a **
- andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
- be L_v1 ! if no, branch
- nop
-/* Add least significant limb separately to align res_ptr and s2_ptr */
- ld [s1_ptr],%g4
- add s1_ptr,4,s1_ptr
- ld [s2_ptr],%g2
- add s2_ptr,4,s2_ptr
- add size,-1,size
- subcc %g4,%g2,%o4
- st %o4,[res_ptr]
- add res_ptr,4,res_ptr
-L_v1: addx %g0,%g0,%o4 ! save cy in register
- cmp size,2 ! if size < 2 ...
- bl Lend2 ! ... branch to tail code
- subcc %g0,%o4,%g0 ! restore cy
-
- ld [s1_ptr+0],%g4
- addcc size,-10,size
- ld [s1_ptr+4],%g1
- ldd [s2_ptr+0],%g2
- blt Lfin1
- subcc %g0,%o4,%g0 ! restore cy
-/* Add blocks of 8 limbs until less than 8 limbs remain */
-Loop1: subxcc %g4,%g2,%o4
- ld [s1_ptr+8],%g4
- subxcc %g1,%g3,%o5
- ld [s1_ptr+12],%g1
- ldd [s2_ptr+8],%g2
- std %o4,[res_ptr+0]
- subxcc %g4,%g2,%o4
- ld [s1_ptr+16],%g4
- subxcc %g1,%g3,%o5
- ld [s1_ptr+20],%g1
- ldd [s2_ptr+16],%g2
- std %o4,[res_ptr+8]
- subxcc %g4,%g2,%o4
- ld [s1_ptr+24],%g4
- subxcc %g1,%g3,%o5
- ld [s1_ptr+28],%g1
- ldd [s2_ptr+24],%g2
- std %o4,[res_ptr+16]
- subxcc %g4,%g2,%o4
- ld [s1_ptr+32],%g4
- subxcc %g1,%g3,%o5
- ld [s1_ptr+36],%g1
- ldd [s2_ptr+32],%g2
- std %o4,[res_ptr+24]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-8,size
- add s1_ptr,32,s1_ptr
- add s2_ptr,32,s2_ptr
- add res_ptr,32,res_ptr
- bge Loop1
- subcc %g0,%o4,%g0 ! restore cy
-
-Lfin1: addcc size,8-2,size
- blt Lend1
- subcc %g0,%o4,%g0 ! restore cy
-/* Add blocks of 2 limbs until less than 2 limbs remain */
-Loope1: subxcc %g4,%g2,%o4
- ld [s1_ptr+8],%g4
- subxcc %g1,%g3,%o5
- ld [s1_ptr+12],%g1
- ldd [s2_ptr+8],%g2
- std %o4,[res_ptr+0]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-2,size
- add s1_ptr,8,s1_ptr
- add s2_ptr,8,s2_ptr
- add res_ptr,8,res_ptr
- bge Loope1
- subcc %g0,%o4,%g0 ! restore cy
-Lend1: subxcc %g4,%g2,%o4
- subxcc %g1,%g3,%o5
- std %o4,[res_ptr+0]
- addx %g0,%g0,%o4 ! save cy in register
-
- andcc size,1,%g0
- be Lret1
- subcc %g0,%o4,%g0 ! restore cy
-/* Add last limb */
- ld [s1_ptr+8],%g4
- ld [s2_ptr+8],%g2
- subxcc %g4,%g2,%o4
- st %o4,[res_ptr+8]
-
-Lret1: retl
- addx %g0,%g0,%o0 ! return carry-out from most sign. limb
-
-L1: xor s1_ptr,res_ptr,%g1
- andcc %g1,4,%g0
- bne L2
- nop
-! ** V1b **
- andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
- be L_v1b ! if no, branch
- nop
-/* Add least significant limb separately to align res_ptr and s1_ptr */
- ld [s2_ptr],%g4
- add s2_ptr,4,s2_ptr
- ld [s1_ptr],%g2
- add s1_ptr,4,s1_ptr
- add size,-1,size
- subcc %g2,%g4,%o4
- st %o4,[res_ptr]
- add res_ptr,4,res_ptr
-L_v1b: addx %g0,%g0,%o4 ! save cy in register
- cmp size,2 ! if size < 2 ...
- bl Lend2 ! ... branch to tail code
- subcc %g0,%o4,%g0 ! restore cy
-
- ld [s2_ptr+0],%g4
- addcc size,-10,size
- ld [s2_ptr+4],%g1
- ldd [s1_ptr+0],%g2
- blt Lfin1b
- subcc %g0,%o4,%g0 ! restore cy
-/* Add blocks of 8 limbs until less than 8 limbs remain */
-Loop1b: subxcc %g2,%g4,%o4
- ld [s2_ptr+8],%g4
- subxcc %g3,%g1,%o5
- ld [s2_ptr+12],%g1
- ldd [s1_ptr+8],%g2
- std %o4,[res_ptr+0]
- subxcc %g2,%g4,%o4
- ld [s2_ptr+16],%g4
- subxcc %g3,%g1,%o5
- ld [s2_ptr+20],%g1
- ldd [s1_ptr+16],%g2
- std %o4,[res_ptr+8]
- subxcc %g2,%g4,%o4
- ld [s2_ptr+24],%g4
- subxcc %g3,%g1,%o5
- ld [s2_ptr+28],%g1
- ldd [s1_ptr+24],%g2
- std %o4,[res_ptr+16]
- subxcc %g2,%g4,%o4
- ld [s2_ptr+32],%g4
- subxcc %g3,%g1,%o5
- ld [s2_ptr+36],%g1
- ldd [s1_ptr+32],%g2
- std %o4,[res_ptr+24]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-8,size
- add s1_ptr,32,s1_ptr
- add s2_ptr,32,s2_ptr
- add res_ptr,32,res_ptr
- bge Loop1b
- subcc %g0,%o4,%g0 ! restore cy
-
-Lfin1b: addcc size,8-2,size
- blt Lend1b
- subcc %g0,%o4,%g0 ! restore cy
-/* Add blocks of 2 limbs until less than 2 limbs remain */
-Loope1b:subxcc %g2,%g4,%o4
- ld [s2_ptr+8],%g4
- subxcc %g3,%g1,%o5
- ld [s2_ptr+12],%g1
- ldd [s1_ptr+8],%g2
- std %o4,[res_ptr+0]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-2,size
- add s1_ptr,8,s1_ptr
- add s2_ptr,8,s2_ptr
- add res_ptr,8,res_ptr
- bge Loope1b
- subcc %g0,%o4,%g0 ! restore cy
-Lend1b: subxcc %g2,%g4,%o4
- subxcc %g3,%g1,%o5
- std %o4,[res_ptr+0]
- addx %g0,%g0,%o4 ! save cy in register
-
- andcc size,1,%g0
- be Lret1b
- subcc %g0,%o4,%g0 ! restore cy
-/* Add last limb */
- ld [s2_ptr+8],%g4
- ld [s1_ptr+8],%g2
- subxcc %g2,%g4,%o4
- st %o4,[res_ptr+8]
-
-Lret1b: retl
- addx %g0,%g0,%o0 ! return carry-out from most sign. limb
-
-! ** V2 **
-/* If we come here, the alignment of s1_ptr and res_ptr as well as the
- alignment of s2_ptr and res_ptr differ. Since there are only two ways
- things can be aligned (that we care about) we now know that the alignment
- of s1_ptr and s2_ptr are the same. */
-
-L2: cmp size,1
- be Ljone
- nop
- andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
- be L_v2 ! if no, branch
- nop
-/* Add least significant limb separately to align s1_ptr and s2_ptr */
- ld [s1_ptr],%g4
- add s1_ptr,4,s1_ptr
- ld [s2_ptr],%g2
- add s2_ptr,4,s2_ptr
- add size,-1,size
- subcc %g4,%g2,%o4
- st %o4,[res_ptr]
- add res_ptr,4,res_ptr
-
-L_v2: addx %g0,%g0,%o4 ! save cy in register
- addcc size,-8,size
- blt Lfin2
- subcc %g0,%o4,%g0 ! restore cy
-/* Add blocks of 8 limbs until less than 8 limbs remain */
-Loop2: ldd [s1_ptr+0],%g2
- ldd [s2_ptr+0],%o4
- subxcc %g2,%o4,%g2
- st %g2,[res_ptr+0]
- subxcc %g3,%o5,%g3
- st %g3,[res_ptr+4]
- ldd [s1_ptr+8],%g2
- ldd [s2_ptr+8],%o4
- subxcc %g2,%o4,%g2
- st %g2,[res_ptr+8]
- subxcc %g3,%o5,%g3
- st %g3,[res_ptr+12]
- ldd [s1_ptr+16],%g2
- ldd [s2_ptr+16],%o4
- subxcc %g2,%o4,%g2
- st %g2,[res_ptr+16]
- subxcc %g3,%o5,%g3
- st %g3,[res_ptr+20]
- ldd [s1_ptr+24],%g2
- ldd [s2_ptr+24],%o4
- subxcc %g2,%o4,%g2
- st %g2,[res_ptr+24]
- subxcc %g3,%o5,%g3
- st %g3,[res_ptr+28]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-8,size
- add s1_ptr,32,s1_ptr
- add s2_ptr,32,s2_ptr
- add res_ptr,32,res_ptr
- bge Loop2
- subcc %g0,%o4,%g0 ! restore cy
-
-Lfin2: addcc size,8-2,size
- blt Lend2
- subcc %g0,%o4,%g0 ! restore cy
-Loope2: ldd [s1_ptr+0],%g2
- ldd [s2_ptr+0],%o4
- subxcc %g2,%o4,%g2
- st %g2,[res_ptr+0]
- subxcc %g3,%o5,%g3
- st %g3,[res_ptr+4]
- addx %g0,%g0,%o4 ! save cy in register
- addcc size,-2,size
- add s1_ptr,8,s1_ptr
- add s2_ptr,8,s2_ptr
- add res_ptr,8,res_ptr
- bge Loope2
- subcc %g0,%o4,%g0 ! restore cy
-Lend2: andcc size,1,%g0
- be Lret2
- subcc %g0,%o4,%g0 ! restore cy
-/* Add last limb */
-Ljone: ld [s1_ptr],%g4
- ld [s2_ptr],%g2
- subxcc %g4,%g2,%o4
- st %o4,[res_ptr]
-
-Lret2: retl
- addx %g0,%g0,%o0 ! return carry-out from most sign. limb
diff --git a/sysdeps/sparc/sys/trap.h b/sysdeps/sparc/sys/trap.h
new file mode 100644
index 0000000000..50be40668f
--- /dev/null
+++ b/sysdeps/sparc/sys/trap.h
@@ -0,0 +1,7 @@
+/* Include trap definitions. */
+#ifndef _SYS_TRAP_H
+#define _SYS_TRAP_H 1
+
+#include <machine/trap.h>
+
+#endif /* sys/trap.h */
diff --git a/sysdeps/unix/sysv/linux/accept.S b/sysdeps/unix/sysv/linux/accept.S
index dfb47d580d..7fa9909b2c 100644
--- a/sysdeps/unix/sysv/linux/accept.S
+++ b/sysdeps/unix/sysv/linux/accept.S
@@ -1,4 +1,5 @@
#define socket accept
+#define NARGS 3
#define __socket __libc_accept
#include <socket.S>
weak_alias (__libc_accept, __accept)
diff --git a/sysdeps/unix/sysv/linux/bind.S b/sysdeps/unix/sysv/linux/bind.S
index fc82b65a2f..400c80aa22 100644
--- a/sysdeps/unix/sysv/linux/bind.S
+++ b/sysdeps/unix/sysv/linux/bind.S
@@ -1,2 +1,3 @@
+#define NARGS 3
#define socket bind
#include <socket.S>
diff --git a/sysdeps/unix/sysv/linux/connect.S b/sysdeps/unix/sysv/linux/connect.S
index 3f3cc618e6..ac7745516e 100644
--- a/sysdeps/unix/sysv/linux/connect.S
+++ b/sysdeps/unix/sysv/linux/connect.S
@@ -1,4 +1,5 @@
#define socket connect
+#define NARGS 3
#define __socket __libc_connect
#include <socket.S>
weak_alias (__libc_connect, __connect)
diff --git a/sysdeps/unix/sysv/linux/getpeername.S b/sysdeps/unix/sysv/linux/getpeername.S
index 8429fcdf76..b24e5041f0 100644
--- a/sysdeps/unix/sysv/linux/getpeername.S
+++ b/sysdeps/unix/sysv/linux/getpeername.S
@@ -1,2 +1,3 @@
+#define NARGS 3
#define socket getpeername
#include <socket.S>
diff --git a/sysdeps/unix/sysv/linux/getsockname.S b/sysdeps/unix/sysv/linux/getsockname.S
index 6782707f88..d4a223f11d 100644
--- a/sysdeps/unix/sysv/linux/getsockname.S
+++ b/sysdeps/unix/sysv/linux/getsockname.S
@@ -1,2 +1,3 @@
+#define NARGS 3
#define socket getsockname
#include <socket.S>
diff --git a/sysdeps/unix/sysv/linux/getsockopt.S b/sysdeps/unix/sysv/linux/getsockopt.S
index 6ce92a6330..bb8fa32802 100644
--- a/sysdeps/unix/sysv/linux/getsockopt.S
+++ b/sysdeps/unix/sysv/linux/getsockopt.S
@@ -1,2 +1,3 @@
+#define NARGS 5
#define socket getsockopt
#include <socket.S>
diff --git a/sysdeps/unix/sysv/linux/listen.S b/sysdeps/unix/sysv/linux/listen.S
index d2cbec60a0..a0d959b661 100644
--- a/sysdeps/unix/sysv/linux/listen.S
+++ b/sysdeps/unix/sysv/linux/listen.S
@@ -1,2 +1,3 @@
+#define NARGS 2
#define socket listen
#include <socket.S>
diff --git a/sysdeps/unix/sysv/linux/recv.S b/sysdeps/unix/sysv/linux/recv.S
index 5763d17d1d..a7ca9982d9 100644
--- a/sysdeps/unix/sysv/linux/recv.S
+++ b/sysdeps/unix/sysv/linux/recv.S
@@ -1,4 +1,5 @@
#define socket recv
+#define NARGS 4
#define __socket __libc_recv
#include <socket.S>
weak_alias (__libc_recv, __recv)
diff --git a/sysdeps/unix/sysv/linux/recvfrom.S b/sysdeps/unix/sysv/linux/recvfrom.S
index 3b2b6509d7..280d19e1be 100644
--- a/sysdeps/unix/sysv/linux/recvfrom.S
+++ b/sysdeps/unix/sysv/linux/recvfrom.S
@@ -1,4 +1,5 @@
#define socket recvfrom
+#define NARGS 6
#define __socket __libc_recvfrom
#include <socket.S>
weak_alias (__libc_recvfrom, __recvfrom)
diff --git a/sysdeps/unix/sysv/linux/recvmsg.S b/sysdeps/unix/sysv/linux/recvmsg.S
index c62cc289b5..6aa27e901b 100644
--- a/sysdeps/unix/sysv/linux/recvmsg.S
+++ b/sysdeps/unix/sysv/linux/recvmsg.S
@@ -1,4 +1,5 @@
#define socket recvmsg
+#define NARGS 3
#define __socket __libc_recvmsg
#include <socket.S>
weak_alias (__libc_recvmsg, __recvmsg)
diff --git a/sysdeps/unix/sysv/linux/send.S b/sysdeps/unix/sysv/linux/send.S
index 253897787c..be7e53427d 100644
--- a/sysdeps/unix/sysv/linux/send.S
+++ b/sysdeps/unix/sysv/linux/send.S
@@ -1,4 +1,5 @@
#define socket send
+#define NARGS 4
#define __socket __libc_send
#include <socket.S>
weak_alias (__libc_send, __send)
diff --git a/sysdeps/unix/sysv/linux/sendmsg.S b/sysdeps/unix/sysv/linux/sendmsg.S
index 1743846bab..e5a939dbc5 100644
--- a/sysdeps/unix/sysv/linux/sendmsg.S
+++ b/sysdeps/unix/sysv/linux/sendmsg.S
@@ -1,4 +1,5 @@
#define socket sendmsg
+#define NARGS 3
#define __socket __libc_sendmsg
#include <socket.S>
weak_alias (__libc_sendmsg, __sendmsg)
diff --git a/sysdeps/unix/sysv/linux/sendto.S b/sysdeps/unix/sysv/linux/sendto.S
index eb82cc1f17..2da10710d9 100644
--- a/sysdeps/unix/sysv/linux/sendto.S
+++ b/sysdeps/unix/sysv/linux/sendto.S
@@ -1,4 +1,5 @@
#define socket sendto
+#define NARGS 6
#define __socket __libc_sendto
#include <socket.S>
weak_alias (__libc_sendto, __sendto)
diff --git a/sysdeps/unix/sysv/linux/setsockopt.S b/sysdeps/unix/sysv/linux/setsockopt.S
index 33d57179ca..3747a09bf7 100644
--- a/sysdeps/unix/sysv/linux/setsockopt.S
+++ b/sysdeps/unix/sysv/linux/setsockopt.S
@@ -1,2 +1,3 @@
+#define NARGS 5
#define socket setsockopt
#include <socket.S>
diff --git a/sysdeps/unix/sysv/linux/shutdown.S b/sysdeps/unix/sysv/linux/shutdown.S
index 6cc95d50f9..d31d65ca08 100644
--- a/sysdeps/unix/sysv/linux/shutdown.S
+++ b/sysdeps/unix/sysv/linux/shutdown.S
@@ -1,2 +1,3 @@
+#define NARGS 2
#define socket shutdown
#include <socket.S>
diff --git a/sysdeps/unix/sysv/linux/socketpair.S b/sysdeps/unix/sysv/linux/socketpair.S
index da71c57dea..e48017a732 100644
--- a/sysdeps/unix/sysv/linux/socketpair.S
+++ b/sysdeps/unix/sysv/linux/socketpair.S
@@ -1,2 +1,3 @@
+#define NARGS 4
#define socket socketpair
#include <socket.S>
diff --git a/sysdeps/unix/sysv/linux/sparc/Dist b/sysdeps/unix/sysv/linux/sparc/Dist
index 6134c6056d..e7569d1ad3 100644
--- a/sysdeps/unix/sysv/linux/sparc/Dist
+++ b/sysdeps/unix/sysv/linux/sparc/Dist
@@ -1,2 +1,2 @@
-__sigtrampoline.S
-clone.S
+sys/kernel_termios.h
+sys/trap.h
diff --git a/sysdeps/unix/sysv/linux/sparc/Makefile b/sysdeps/unix/sysv/linux/sparc/Makefile
deleted file mode 100644
index 629e6b37df..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-ifeq ($(subdir),signal)
-sysdep_routines += __sigtrampoline
-endif
diff --git a/sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S b/sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S
deleted file mode 100644
index 4fea850ee3..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Userland trampoline code for sigaction on Linux/SPARC */
-/* (C) 1996, 1997 Free Software Foundation, Inc. */
-/* This file is part of the GNU C Library. */
-/* Contributed by Miguel de Icaza (miguel@gnu.ai.mit.edu) */
-/* Many thanks go to David Miller for explaining all this to me */
-/* miguel@nuclecu.unam.mx */
-/* Sources: David Miller, 4.4BSD/SPARC code */
-
-#include <sysdep.h>
-
-/* For REGWIN_SZ */
-#include <asm/ptrace.h>
-#include <asm/psr.h>
-
-/* The C compiler frame size */
-#define CCFSZ 96
-
- .text
-
-ENTRY(____sparc_signal_trampoline)
- .global SYMBOL_NAME(____sig_table)
-
- /* Make room for 32 %f registers + %fsr
- * this is 132 bytes + alignement = 136
- * 96 is the C frame size
- */
- save %sp,-136-CCFSZ,%sp
-
- /* save regular registers */
- mov %g2,%l2
- mov %g3,%l3
- mov %g4,%l4
- mov %g5,%l5
- mov %g6,%l6
- mov %g7,%l7
-
- /* save fpu registers */
- ld [%fp+64+16+20],%l0 /* load the psr from sigcontext */
- sethi %hi(PSR_EF),%l1
- andcc %l0,%l1,%l0 /* is floating point enabled? */
- be 1f
- rd %y,%l1 /* save y anyways */
-
- /* save fpu registers */
- st %fsr, [%sp + CCFSZ + 0]
- std %f0, [%sp + CCFSZ + 8]
- std %f2, [%sp + CCFSZ + 16]
- std %f4, [%sp + CCFSZ + 24]
- std %f6, [%sp + CCFSZ + 32]
- std %f8, [%sp + CCFSZ + 40]
- std %f10, [%sp + CCFSZ + 48]
- std %f12, [%sp + CCFSZ + 56]
- std %f14, [%sp + CCFSZ + 64]
- std %f16, [%sp + CCFSZ + 72]
- std %f18, [%sp + CCFSZ + 80]
- std %f20, [%sp + CCFSZ + 88]
- std %f22, [%sp + CCFSZ + 96]
- std %f24, [%sp + CCFSZ + 104]
- std %f26, [%sp + CCFSZ + 112]
- std %f28, [%sp + CCFSZ + 120]
- std %f30, [%sp + CCFSZ + 128]
-
-1:
- /* Load signal number */
- ld [%fp + REGWIN_SZ],%o0
- mov %fp,%o1
- mov 0xfea,%o2
-
- /* Sanity check */
- cmp %o0,33
- bl 1f
- or %g0,%g0,%g1 /*Call sys_setup */
- t 0x10
-1:
-#ifdef __PIC__
- /* Save return address */
- mov %o7,%o4
-___sxx:
- call ___syy
- nop
-___syy:
- sethi %hi(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
- or %o5,%lo(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
- add %o7,%o5,%o5
- /* restore return address */
- mov %o4,%o7
- mov %o5,%o4
- /* o4 has the GOT pointer */
-#endif
- sethi %hi(SYMBOL_NAME(____sig_table)),%o5
- or %o5,%lo(SYMBOL_NAME(____sig_table)),%o5
-#ifdef __PIC__
- add %o5,%o4,%o4
- ld [%o4],%o5
-#endif
- sll %o0,2,%o4
- add %o5,%o4,%o4
- ld [%o4],%o4
- ld [%fp + REGWIN_SZ + 4],%o1 /* Load subcode */
- ld [%fp + REGWIN_SZ + 8],%o2 /* pointer to sigcontext */
- call %o4
- ld [%fp + REGWIN_SZ + 12],%o3 /* Address where signal occurred */
-
- /* handler returned, restore state */
- tst %l0
- be 1f
- wr %l1,%g0,%y
-
- /* fpu restoration */
- ld [%sp + CCFSZ + 0], %fsr
- ldd [%sp + CCFSZ + 8], %f0
- ldd [%sp + CCFSZ + 16], %f2
- ldd [%sp + CCFSZ + 24], %f4
- ldd [%sp + CCFSZ + 32], %f6
- ldd [%sp + CCFSZ + 40], %f8
- ldd [%sp + CCFSZ + 48], %f10
- ldd [%sp + CCFSZ + 56], %f12
- ldd [%sp + CCFSZ + 64], %f14
- ldd [%sp + CCFSZ + 72], %f16
- ldd [%sp + CCFSZ + 80], %f18
- ldd [%sp + CCFSZ + 88], %f20
- ldd [%sp + CCFSZ + 96], %f22
- ldd [%sp + CCFSZ + 104], %f24
- ldd [%sp + CCFSZ + 112], %f26
- ldd [%sp + CCFSZ + 120], %f28
- ldd [%sp + CCFSZ + 128], %f30
-
-1:
- mov %l2,%g2
- mov %l3,%g3
- mov %l4,%g4
- mov %l5,%g5
- mov %l6,%g6
- mov %l7,%g7
-
- /* call sigreturn */
- restore %g0,SYS_sigreturn,%g1 /* register back and set syscall */
- add %sp,64+16,%o0
- t 0x10
- /* if we return, sysreturn failed */
- mov SYS_exit,%g1
- t 0x10
diff --git a/sysdeps/unix/sysv/linux/sparc/fcntlbits.h b/sysdeps/unix/sysv/linux/sparc/fcntlbits.h
new file mode 100644
index 0000000000..9e8c589b9a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/fcntlbits.h
@@ -0,0 +1,125 @@
+/* O_*, F_*, FD_* bit values for Linux/SPARC.
+ Copyright (C) 1995, 1996, 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. */
+
+#ifndef _FCNTLBITS_H
+#define _FCNTLBITS_H 1
+
+#include <sys/types.h>
+
+/* In GNU, read and write are bits (unlike BSD). */
+#ifdef __USE_GNU
+# define O_READ O_RDONLY /* Open for reading. */
+# define O_WRITE O_WRONLY /* Open for writing. */
+#endif
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_RDONLY 0x0000
+#define O_WRONLY 0x0001
+#define O_RDWR 0x0002
+#define O_ACCMODE 0x0003
+#define O_APPEND 0x0008
+#define O_ASYNC 0x0040
+#define O_CREAT 0x0200 /* not fcntl */
+#define O_TRUNC 0x0400 /* not fcntl */
+#define O_EXCL 0x0800 /* not fcntl */
+#define O_SYNC 0x2000
+#define O_NONBLOCK 0x4000
+#define O_NDELAY (0x0004 | O_NONBLOCK)
+#define O_NOCTTY 0x8000 /* not fcntl */
+
+/* XXX missing */
+#define O_LARGEFILE 0
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#ifdef __USE_BSD
+# define F_GETOWN 5 /* Get owner of socket (receiver of SIGIO). */
+# define F_SETOWN 6 /* Set owner of socket (receiver of SIGIO). */
+#endif
+#define F_GETLK 7 /* Get record locking info. */
+#define F_SETLK 8 /* Set record locking info (non-blocking). */
+#define F_SETLKW 9 /* Set record locking info (blocking). */
+
+/* XXX missing */
+#define F_GETLK64 7 /* Get record locking info. */
+#define F_SETLK64 8 /* Set record locking info (non-blocking). */
+#define F_SETLKW64 9 /* Set record locking info (blocking). */
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 1 /* Read lock. */
+#define F_WRLCK 2 /* Write lock. */
+#define F_UNLCK 3 /* Remove lock. */
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH 1 /* shared lock */
+#define LOCK_EX 2 /* exclusive lock */
+#define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+#define LOCK_UN 8 /* remove lock */
+
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ short int __unused;
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ short int __unused;
+ };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/ioctls.h b/sysdeps/unix/sysv/linux/sparc/ioctls.h
new file mode 100644
index 0000000000..6df4780634
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/ioctls.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 1996, 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. */
+
+#ifndef _IOCTLS_H
+#define _IOCTLS_H 1
+
+/* Use the definitions from the kernel header files. */
+#include <asm/ioctls.h>
+#include <sys/kernel_termios.h>
+
+/* Oh well, this is necessary since the kernel data structure is
+ different from the user-level version. */
+#undef TCGETS
+#undef TCSETS
+#undef TCSETSW
+#undef TCSETSF
+#define TCGETS _IOR ('T', 8, char[36])
+#define TCSETS _IOW ('T', 9, char[36])
+#define TCSETSW _IOW ('T', 10, char[36])
+#define TCSETSF _IOW ('T', 11, char[36])
+
+#include <linux/sockios.h>
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sigaction.h b/sysdeps/unix/sysv/linux/sparc/sigaction.h
new file mode 100644
index 0000000000..5cde59288e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sigaction.h
@@ -0,0 +1,55 @@
+/* The proper definitions for Linux/SPARC sigaction.
+ Copyright (C) 1996, 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. */
+
+/* Structure describing the action to be taken when a signal arrives. */
+struct sigaction
+ {
+ /* Signal handler. */
+ __sighandler_t sa_handler;
+
+ /* Additional set of signals to be blocked. */
+ __sigset_t sa_mask;
+
+ /* Special flags. */
+ unsigned long sa_flags;
+
+ /* Not used by Linux/Sparc yet. */
+ void (*sa_restorer) __P ((void));
+ };
+
+
+/* Bits in `sa_flags'. */
+#define SA_NOCLDSTOP 0x00000008 /* Don't send SIGCHLD when children stop. */
+#ifdef __USE_MISC
+# define SA_STACK 0x00000001 /* Use signal stack by using `sa_restorer'. */
+# define SA_RESTART 0x00000002 /* Restart syscall on signal return. */
+# define SA_INTERRUPT 0x00000010 /* Historical no-op. */
+# define SA_NOMASK 0x00000020 /* Don't automatically block the signal when
+ its handler is being executed. */
+# define SA_ONESHOT 0x00000004 /* Reset to SIG_DFL on entry to handler. */
+
+/* Some aliases for the SA_ constants. */
+# define SA_NODEFER SA_NOMASK
+# define SA_RESETHAND SA_ONESHOT
+#endif
+
+/* Values for the HOW argument to `sigprocmask'. */
+#define SIG_BLOCK 1 /* Block signals. */
+#define SIG_UNBLOCK 2 /* Unblock signals. */
+#define SIG_SETMASK 4 /* Set the set of blocked signals. */
diff --git a/sysdeps/unix/sysv/linux/sparc/signum.h b/sysdeps/unix/sysv/linux/sparc/signum.h
new file mode 100644
index 0000000000..3437c16113
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/signum.h
@@ -0,0 +1,69 @@
+/* Signal number definitions. Linux/SPARC version.
+ Copyright (C) 1996, 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. */
+
+#ifdef _SIGNAL_H
+
+/* Fake signal functions. */
+#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
+#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
+#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
+
+/*
+ * Linux/SPARC has different signal numbers that Linux/i386: I'm trying
+ * to make it OSF/1 binary compatible, at least for normal binaries.
+ */
+#define _NSIG 32 /* Biggest signal number + 1. */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGEMT 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGBUS 10
+#define SIGSEGV 11
+#define SIGSYS 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGURG 16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP 17
+#define SIGTSTP 18
+#define SIGCONT 19
+#define SIGCHLD 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGIO 23
+#define SIGPOLL SIGIO /* SysV name for SIGIO */
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGLOST 29
+#define SIGUSR1 30
+#define SIGUSR2 31
+
+#endif /* <signal.h> included. */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Dist b/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
new file mode 100644
index 0000000000..ed8fc080c1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
@@ -0,0 +1,7 @@
+__sigtrampoline.S
+bits/mman.h
+clone.S
+pipe.S
+fork.S
+kernel_stat.h
+init-first.h
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile b/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile
new file mode 100644
index 0000000000..01a0e8310f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile
@@ -0,0 +1,12 @@
+ifeq ($(subdir),signal)
+sysdep_routines += __sigtrampoline
+endif
+
+asm-CPPFLAGS=-D__ASSEMBLY__
+ASFLAGS-.os=-fPIC
+
+# When I get this to work, this is the right thing
+ifeq ($(subdir),elf)
+CFLAGS-rtld.c += -mv8
+#rtld-routines += dl-sysdepsparc
+endif # elf
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/__sigtrampoline.S b/sysdeps/unix/sysv/linux/sparc/sparc32/__sigtrampoline.S
new file mode 100644
index 0000000000..8e88a3ff04
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/__sigtrampoline.S
@@ -0,0 +1,140 @@
+/* Userland trampoline code for sigaction on Linux/SPARC */
+/* (C) 1996, 1997 Free Software Foundation, Inc. */
+/* This file is part of the GNU C Library. */
+/* Contributed by Miguel de Icaza (miguel@gnu.ai.mit.edu) */
+/* Many thanks go to David Miller for explaining all this to me */
+/* miguel@nuclecu.unam.mx */
+/* Sources: David Miller, 4.4BSD/SPARC code */
+
+#include <sysdep.h>
+#define __ASSEMBLY__
+/* For REGWIN_SZ */
+#include <asm/ptrace.h>
+#include <asm/psr.h>
+
+/* The C compiler frame size */
+#define CCFSZ 96
+
+ .text
+
+ENTRY(____sparc_signal_trampoline)
+ .global C_SYMBOL_NAME(____sig_table)
+
+ /* Make room for 32 %f registers + %fsr
+ * this is 132 bytes + alignement = 136
+ * 96 is the C frame size
+ */
+ save %sp,-136-CCFSZ,%sp
+
+ /* save regular registers */
+ mov %g2,%l2
+ mov %g3,%l3
+ mov %g4,%l4
+ mov %g5,%l5
+ mov %g6,%l6
+ mov %g7,%l7
+
+ /* save fpu registers */
+ ld [%fp+64+16+20],%l0 /* load the psr from sigcontext */
+ sethi %hi(PSR_EF),%l1
+ andcc %l0,%l1,%l0 /* is floating point enabled? */
+ be 1f
+ rd %y,%l1 /* save y anyways */
+
+ /* save fpu registers */
+ st %fsr, [%sp + CCFSZ + 0]
+ std %f0, [%sp + CCFSZ + 8]
+ std %f2, [%sp + CCFSZ + 16]
+ std %f4, [%sp + CCFSZ + 24]
+ std %f6, [%sp + CCFSZ + 32]
+ std %f8, [%sp + CCFSZ + 40]
+ std %f10, [%sp + CCFSZ + 48]
+ std %f12, [%sp + CCFSZ + 56]
+ std %f14, [%sp + CCFSZ + 64]
+ std %f16, [%sp + CCFSZ + 72]
+ std %f18, [%sp + CCFSZ + 80]
+ std %f20, [%sp + CCFSZ + 88]
+ std %f22, [%sp + CCFSZ + 96]
+ std %f24, [%sp + CCFSZ + 104]
+ std %f26, [%sp + CCFSZ + 112]
+ std %f28, [%sp + CCFSZ + 120]
+ std %f30, [%sp + CCFSZ + 128]
+
+1:
+ /* Load signal number */
+ ld [%fp + REGWIN_SZ],%o0
+ mov %fp,%o1
+ mov 0xfea,%o2
+
+ /* Sanity check */
+ cmp %o0,33
+ bl 1f
+ or %g0,%g0,%g1 /*Call sys_setup */
+ t 0x10
+1:
+#ifdef PIC
+ /* Save return address */
+ mov %o7,%o5
+11: call 12f
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(11b-.)),%o4
+12: or %o5,%lo(_GLOBAL_OFFSET_TABLE_-(11b-.)),%o4
+ add %o7,%o4,%o4
+ /* restore return address */
+ mov %o5,%o7
+ /* o4 has the GOT pointer */
+#endif
+ sethi %hi(C_SYMBOL_NAME(____sig_table)),%o5
+ or %o5,%lo(C_SYMBOL_NAME(____sig_table)),%o5
+#ifdef PIC
+ ld [%o4+%o5], %o5
+#endif
+ sll %o0,2,%o4
+ add %o5,%o4,%o4
+ ld [%o4],%o4
+ ld [%fp + REGWIN_SZ + 4],%o1 /* Load subcode */
+ ld [%fp + REGWIN_SZ + 8],%o2 /* pointer to sigcontext */
+ call %o4
+ ld [%fp + REGWIN_SZ + 12],%o3 /* Address where signal ocurre
+ */
+
+ /* handler returned, restore state */
+ tst %l0
+ be 1f
+ wr %l1,%g0,%y
+
+ /* fpu restoration */
+ ld [%sp + CCFSZ + 0], %fsr
+ ldd [%sp + CCFSZ + 8], %f0
+ ldd [%sp + CCFSZ + 16], %f2
+ ldd [%sp + CCFSZ + 24], %f4
+ ldd [%sp + CCFSZ + 32], %f6
+ ldd [%sp + CCFSZ + 40], %f8
+ ldd [%sp + CCFSZ + 48], %f10
+ ldd [%sp + CCFSZ + 56], %f12
+ ldd [%sp + CCFSZ + 64], %f14
+ ldd [%sp + CCFSZ + 72], %f16
+ ldd [%sp + CCFSZ + 80], %f18
+ ldd [%sp + CCFSZ + 88], %f20
+ ldd [%sp + CCFSZ + 96], %f22
+ ldd [%sp + CCFSZ + 104], %f24
+ ldd [%sp + CCFSZ + 112], %f26
+ ldd [%sp + CCFSZ + 120], %f28
+ ldd [%sp + CCFSZ + 128], %f30
+
+1:
+ mov %l2,%g2
+ mov %l3,%g3
+ mov %l4,%g4
+ mov %l5,%g5
+ mov %l6,%g6
+ mov %l7,%g7
+
+ /* call sigreturn */
+ restore %g0,SYS_ify(sigreturn),%g1 /* register back and set syscal */
+ add %sp,64+16,%o0
+ t 0x10
+ /* if we return, sysreturn failed */
+ mov SYS_ify(exit),%g1
+ t 0x10
+
+END(____sparc_signal_trampoline)
diff --git a/sysdeps/unix/sysv/linux/sparc/brk.c b/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c
index 13bcb0459b..101f1ad2ff 100644
--- a/sysdeps/unix/sysv/linux/sparc/brk.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c
@@ -35,13 +35,12 @@ __brk (void *addr)
{
void *newbrk, *scratch;
- asm ("mov %1, %%g1\n\t"
- "mov %2, %%o0\n\t"
- "t 0x10\n\t"
- "mov %%o0, %0\n\t"
- : "=r" (newbrk)
- : "0" (SYS_brk), "r" (addr)
- : "g1", "o0");
+ {
+ register void *o0 __asm__("%o0") = addr;
+ register int g1 __asm__("%g1") = __NR_brk;
+ __asm ("t 0x10" : "=r"(o0) : "r"(g1), "0"(o0) : "cc");
+ newbrk = o0;
+ }
__curbrk = newbrk;
diff --git a/sysdeps/unix/sysv/linux/sparc/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
index 64735e9dbc..cdc9a2e015 100644
--- a/sysdeps/unix/sysv/linux/sparc/clone.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
@@ -29,6 +29,7 @@
.globl __libc_clone
.type __libc_clone,@function
.weak clone
+ .weak __clone
__clone = __libc_clone
clone = __libc_clone
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/fork.S b/sysdeps/unix/sysv/linux/sparc/sparc32/fork.S
new file mode 100644
index 0000000000..951ab4981b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/fork.S
@@ -0,0 +1,33 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@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>
+
+PSEUDO (__libc_fork, fork, 0)
+ tst %o1
+ be,a parent
+ nop
+ /* child: return 0 */
+ clr %o0
+parent:
+ ret
+
+PSEUDO_END (__libc_fork)
+weak_alias (__libc_fork, __fork)
+weak_alias (__libc_fork, fork)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c b/sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c
new file mode 100644
index 0000000000..e04e926644
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/init-first.h b/sysdeps/unix/sysv/linux/sparc/sparc32/init-first.h
new file mode 100644
index 0000000000..384c5c219b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/init-first.h
@@ -0,0 +1,96 @@
+/* Prepare arguments for library initialization function.
+ 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. */
+
+/* The job of this fragment it to find argc and friends for INIT.
+ This is done in one of two ways: either in the stack context
+ of program start, or having dlopen pass them in. */
+
+#include <sysdep.h>
+
+#define __S1(x) #x
+#define __S(x) __S1(x)
+
+#ifdef PIC
+
+#define SYSDEP_CALL_INIT(NAME, INIT) asm("\
+ .weak _dl_starting_up
+ .global " #NAME "
+ .type " #NAME ",@function
+" #NAME ":
+ save %sp, -64, %sp
+1: call 11f
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+11: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+ add %l7, %o7, %l7
+ /* Are we a dynamic libc being loaded into a static program? */
+ sethi %hi(_dl_starting_up), %l2
+ or %l2, %lo(_dl_starting_up), %l2
+ ld [%l7+%l2], %l2
+ cmp %l2, 0
+ beq 3f
+ sethi %hi(__libc_multiple_libcs), %l3
+ ld [%l2], %l2
+ subcc %g0, %l2, %g0
+ subx %g0, -1, %l2
+3: or %l3, %lo(__libc_multiple_libcs), %l3
+ ld [%l7+%l3], %l3
+ cmp %l2, 0
+ st %l2, [%l3]
+ /* If so, argc et al are in %o0-%o2 already. Otherwise, load them. */
+ bnz " #INIT "
+ restore
+ ld [%sp+22*4], %o0
+ add %sp, 23*4, %o1
+ sll %o0, 2, %o2
+ add %o2, %o1, %o2
+ ba " #INIT "
+ add %o2, 4, %o2
+ .size "#NAME ", .-" #NAME);
+
+#else
+
+#define SYSDEP_CALL_INIT(NAME, INIT) asm("\
+ .weak _dl_starting_up
+ .global " #NAME "
+ .type " #NAME ",@function
+" #NAME ":
+ /* Are we a dynamic libc being loaded into a static program? */
+ sethi %hi(_dl_starting_up), %g2
+ or %g2, %lo(_dl_starting_up), %g2
+ cmp %g2, 0
+ beq 3f
+ sethi %hi(__libc_multiple_libcs), %g3
+ ld [%g2], %g2
+ subcc %g0, %g2, %g0
+ subx %g0, -1, %g2
+3: or %g3, %lo(__libc_multiple_libcs), %g3
+ cmp %g2, 0
+ st %g2, [%g3]
+ /* 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
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
new file mode 100644
index 0000000000..91f02f4e20
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
@@ -0,0 +1,28 @@
+/* Definition of `struct stat' used in the kernel */
+struct kernel_stat
+ {
+ unsigned short int st_dev;
+ unsigned long int st_ino;
+ unsigned short int st_mode;
+ short int st_nlink;
+ unsigned short int st_uid;
+ unsigned short int st_gid;
+ unsigned short int st_rdev;
+ long int st_size;
+ long int st_atime;
+ unsigned long int __unused1;
+ long int st_mtime;
+ unsigned long int __unused2;
+ long int st_ctime;
+ unsigned long int __unused3;
+ long int st_blksize;
+ long int st_blocks;
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ };
+
+#define _HAVE___UNUSED1
+#define _HAVE___UNUSED2
+#define _HAVE___UNUSED3
+#define _HAVE___UNUSED4
+#define _HAVE___UNUSED5
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S b/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
new file mode 100644
index 0000000000..4c50656d6c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
@@ -0,0 +1,37 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@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>
+ .globl __libc_pipe
+ENTRY (__libc_pipe)
+ mov %o0, %o2 /* Save PIPEDES. */
+ mov SYS_ify(pipe),%g1
+ ta 0x10
+ bcc,a 2f
+ nop
+ SYSCALL_ERROR_HANDLER
+2:
+ st %o0, [%o2] /* PIPEDES[0] = %o0; */
+ st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */
+ retl
+ clr %o0
+
+PSEUDO_END (__libc_pipe)
+weak_alias (__libc_pipe, __pipe)
+weak_alias (__libc_pipe, pipe)
diff --git a/sysdeps/unix/sysv/linux/sparc/profil-counter.h b/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h
index 1998c34ed5..1bd06482c9 100644
--- a/sysdeps/unix/sysv/linux/sparc/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h
@@ -17,19 +17,10 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <sigcontext.h>
+#include <signal.h>
void
profil_counter (int signo, __siginfo_t si)
{
- extern int __sparc_old_signals;
-
- if (__sparc_old_signals)
- {
- struct sigcontext_struct *s = (void *) &si;
-
- profil_count ((void *) s->sigc_pc);
- }
- else
- profil_count ((void *) si.si_regs.pc);
+ profil_count ((void *) si.si_regs.pc);
}
diff --git a/sysdeps/unix/sysv/linux/sparc/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
index e7bda77de2..eed0f1e4b0 100644
--- a/sysdeps/unix/sysv/linux/sparc/sigaction.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
@@ -21,6 +21,11 @@
#include <syscall.h>
#include <sys/signal.h>
#include <errno.h>
+#include <kernel_sigaction.h>
+
+/* Commented out while I figure out what the fuck goes on */
+long ____sig_table [NSIG];
+#if 0
/* The kernel will deliver signals in the old way if the signal
number is a positive number. The kernel will deliver a signal
@@ -30,7 +35,6 @@
using at runtime. */
extern void ____sparc_signal_trampoline (int);
-long ____sig_table [NSIG];
int
__trampoline_sigaction (int sig, struct sigaction *new, struct sigaction *old)
@@ -60,7 +64,7 @@ __trampoline_sigaction (int sig, struct sigaction *new, struct sigaction *old)
"1:"
: "=r" (ret), "=r" ((long int) sig), "=r" ((long int) new),
"=r" ((long int) old)
- : "0" (SYS_sigaction), "1" (sig), "2" (new), "3" (old)
+ : "0" (__NR_sigaction), "1" (sig), "2" (new), "3" (old)
: "g1", "o0", "o1", "o2");
if (ret >= 0)
@@ -79,37 +83,54 @@ __trampoline_sigaction (int sig, struct sigaction *new, struct sigaction *old)
__set_errno (-ret);
return -1;
}
+#else
+# define __new_sigaction __sigaction
+#endif
int
-__new_sigaction (int sig, struct sigaction *new, struct sigaction *old)
+__new_sigaction (int sig, __const struct sigaction *act, struct sigaction *oact)
{
int ret;
+ struct kernel_sigaction k_sigact, k_osigact;
sig = -sig;
- __asm__("or %%g0,%0,%%g1\n\t"
- "or %%g0,%1,%%o0\n\t"
- "or %%g0,%2,%%o1\n\t"
- "or %%g0,%3,%%o2\n\t"
+ if (act)
+ {
+ k_sigact.sa_handler = act->sa_handler;
+ k_sigact.sa_mask = act->sa_mask.__val[0];
+ k_sigact.sa_flags = act->sa_flags;
+ }
+ __asm__("mov %1,%%g1\n\t"
+ "mov %2,%%o0\n\t"
+ "mov %3,%%o1\n\t"
+ "mov %4,%%o2\n\t"
"t 0x10\n\t"
"bcc 1f\n\t"
- "or %%o0, %%g0, %0\n\t"
+ " mov %%o0, %0\n\t"
"sub %%g0,%%o0,%0\n\t"
"1:"
- : "=r" (ret), "=r" ((long int) sig), "=r" ((long int) new),
- "=r" ((long int) old)
- : "0" (SYS_sigaction), "1" (sig), "2" (new), "3" (old)
+ : "=r" (ret)
+ : "i" (__NR_sigaction), "r" (sig), "r" (act ? &k_sigact : NULL),
+ "r" (oact ? &k_osigact : NULL)
: "g1", "o0", "o1", "o2");
- if (ret >= 0)
- return 0;
- __set_errno (-ret);
- return -1;
+ if (ret < 0)
+ __set_errno (-ret);
+ if (oact)
+ {
+ oact->sa_handler = k_osigact.sa_handler;
+ oact->sa_mask.__val[0] = k_osigact.sa_mask;
+ oact->sa_flags = k_osigact.sa_flags;
+ oact->sa_restorer = NULL;
+ }
+ return 0;
}
+#if 0
int
-__sigaction (int sig, struct sigaction *new, struct sigaction *old)
+__sigaction (int sig, __const struct sigaction *new, struct sigaction *old)
{
- static (*sigact_routine) (int, struct sigaction *, struct sigaction *);
+ static (*sigact_routine) (int, __const struct sigaction *, struct sigaction *);
int ret;
struct sigaction sa;
@@ -124,4 +145,6 @@ __sigaction (int sig, struct sigaction *new, struct sigaction *old)
return __sigaction (sig, new, old);
}
+#endif
+
weak_alias (__sigaction, sigaction);
diff --git a/sysdeps/unix/sysv/linux/sparc/socket.S b/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
index 9e3d87996a..29305ec5e2 100644
--- a/sysdeps/unix/sysv/linux/sparc/socket.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
@@ -23,6 +23,14 @@
#define P(a, b) P2(a, b)
#define P2(a, b) a##b
+#ifndef NARGS
+#ifdef socket
+#error NARGS not defined
+#else
+#define NARGS 3
+#endif
+#endif
+
.text
/* The socket-oriented system calls are handled unusually in Linux.
They are all gated through the single `socketcall' system call number.
@@ -38,25 +46,36 @@
.globl __socket
ENTRY (__socket)
- mov SYS_ify(socketcall), %g1 /* System call number */
- /* Use ## so `socket' is a separate token that might be #define'd. */
- mov P(SOCKOP_,socket), %o0 /* Subcode is first arg to syscall. */
- mov %i0,%o1 /* args pointer is second arg to syscall */
+ /* Drop up to 6 arguments (recvfrom) into the memory allocated by
+ the caller for varargs, since that's really what we have. */
+ st %o0, [%sp + 68 + 0]
+ st %o1, [%sp + 68 + 4]
+#if NARGS > 2
+ st %o2, [%sp + 68 + 8]
+#if NARGS > 3
+ st %o3, [%sp + 68 + 12]
+#if NARGS > 4
+ st %o4, [%sp + 68 + 16]
+#if NARGS > 5
+ st %o5, [%sp + 68 + 20]
+#endif
+#endif
+#endif
+#endif
+ mov P(SOCKOP_,socket), %o0 /* arg 1: socket subfunction */
+ add %sp, 68, %o1 /* arg 2: parameter block */
+ LOADSYSCALL(socketcall)
t 0x10
- bcc,a 1
- nop
- save %sp,96,%sp
- call __errno_location
- nop
- st %i0,[%o0]
- restore
+
+ bcs,a 1f
+ nop
retl
- mov -1,%o0
-1:
- ret
+ nop
+
+1: SYSCALL_ERROR_HANDLER
-PSEUDO_END (__socket)
+END (__socket)
weak_alias (__socket, socket)
diff --git a/sysdeps/unix/sysv/linux/sparc/syscall.S b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
index 4166e4231b..3921ca52dc 100644
--- a/sysdeps/unix/sysv/linux/sparc/syscall.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
@@ -16,15 +16,26 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define DONT_LOAD_G1
#include <sysdep.h>
-ENTRY (__libc_syscall)
+ .text
+ENTRY (syscall)
or %o0,%g0,%g1
or %o1,%g0,%o0
or %o2,%g0,%o1
or %o3,%g0,%o2
or %o4,%g0,%o3
or %o5,%g0,%o4
-PSEUDO_NOENT(__libc_syscall, syscall, 5)
+ ta 0x10
+ bcc 1f
+ nop
+ save %sp, -96, %sp
+ call __errno_location
+ nop
+ st %i0,[%o0]
+ restore
+ retl
+ mov -1, %o0
+1:
ret
-SYSCALL__POST(syscall,5)
+
+PSEUDO_END (syscall)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list
new file mode 100644
index 0000000000..7883d70719
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list
@@ -0,0 +1,3 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+s_llseek llseek _llseek 5 __sys_llseek
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.S b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.S
new file mode 100644
index 0000000000..7e9023901b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.S
@@ -0,0 +1,3 @@
+/* Define errno */
+
+ .common errno,4,4
diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
index 0251a1f014..730332f367 100644
--- a/sysdeps/unix/sysv/linux/sparc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
@@ -30,27 +30,57 @@
#ifdef DONT_LOAD_G1
# define LOADSYSCALL(x)
#else
-# define LOADSYSCALL(x) mov SYS_##n, %g1
+# define LOADSYSCALL(x) mov __NR_##x, %g1
#endif
-/* Linux/SPARC uses a different trap number and uses __errno_location always */
+/* Linux/SPARC uses a different trap number */
#undef PSEUDO
+#undef ENTRY
+#undef END
+#undef LOC
-#define PSEUDO(name, syscall_name, args) \
- .text; \
- ENTRY(name); \
- LOADSYSCALL(syscall_name); \
- ta 0x10; \
- bcc,a 1f; \
- nop; \
- save %sp,96,%sp; \
- call __errno_location; \
- nop; \
- st %i0,[%o0]; \
- restore; \
- retl; \
- mov -1,%o0; \
-1:
+#define ENTRY(name) \
+ .global C_SYMBOL_NAME(name); \
+ .align 4;\
+ C_LABEL(name);\
+ .type name,@function;
+
+#define END(name) \
+ .size name, . - name
+
+#define LOC(name) . ## L ## name
+
+#ifdef PIC
+#define SYSCALL_ERROR_HANDLER \
+ .global C_SYMBOL_NAME(__errno_location); \
+ .type C_SYMBOL_NAME(__errno_location),@function; \
+ save %sp,-96,%sp; \
+ call __errno_location; \
+ nop; \
+ st %i0,[%o0]; \
+ restore; \
+ retl; \
+ mov -1,%o0;
+#else
+#define SYSCALL_ERROR_HANDLER \
+ save %sp,-96,%sp; \
+ call __errno_location; \
+ nop; \
+ st %i0,[%o0]; \
+ restore; \
+ retl; \
+ mov -1,%o0;
+#endif /* PIC */
+
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY(name); \
+ LOADSYSCALL(syscall_name); \
+ ta 0x10; \
+ bcc,a 9000f; \
+ nop; \
+ SYSCALL_ERROR_HANDLER; \
+9000:;
#endif /* ASSEMBLER */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Dist b/sysdeps/unix/sysv/linux/sparc/sparc64/Dist
new file mode 100644
index 0000000000..e770e20eb9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Dist
@@ -0,0 +1,7 @@
+bits/mman.h
+clone.S
+kernel_stat.h
+getcontext.S
+setcontext.S
+ucontext.h
+init-first.h
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
new file mode 100644
index 0000000000..c4d83226a2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
@@ -0,0 +1,4 @@
+ifeq ($(subdir),misc)
+sysdep_headers += ucontext.h
+sysdep_routines += getcontext setcontext
+endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/__longjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/__longjmp.S
new file mode 100644
index 0000000000..3107179fdc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/__longjmp.S
@@ -0,0 +1 @@
+/* There is no need for __longjmp what with setcontext. */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
new file mode 100644
index 0000000000..abdd7e6604
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
@@ -0,0 +1,97 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ 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. */
+
+/* __brk is a special syscall under Linux since it never returns an
+ error. Instead, the error condition is indicated by returning the old
+ break value (instead of the new, requested one). */
+
+#include <sysdep.h>
+#define _ERRNO_H
+#include <bits/errno.h>
+
+#ifdef PIC
+.section .bss
+ .align 8
+ .globl __curbrk
+__curbrk: .skip 8
+ .type __curbrk,@object
+ .size __curbrk,8
+#else
+.common __curbrk, 8, 8
+#endif
+
+ .text
+ENTRY(__brk)
+ save %sp, -160, %sp
+#ifdef PIC
+1: call 2f
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+ add %l7, %o7, %l7
+#endif
+
+ LOADSYSCALL(brk)
+ mov %i0, %o0
+
+ ta 0x11
+
+ /* All the ways we can fail... */
+ bcs,pn %xcc, .Lerr1
+ nop
+ brz %i0, .Lok
+ subcc %i0, %o0, %g0
+ bne,pn %xcc, .Lerr0
+
+ /* Update __curbrk and return cleanly. */
+.Lok: sethi %hi(__curbrk), %g1
+ or %g1, %lo(__curbrk), %g1
+#ifdef PIC
+ ldx [%l7+%g1], %g1
+ stx %o0, [%g1]
+#else
+ stx %o0, [%g4+%g1]
+#endif
+ mov %g0, %i0
+
+ /* Don't use "ret" cause the preprocessor will eat it. */
+ jmpl %i7+8, %g0
+ restore
+
+ /* What a horrible way to die. */
+.Lerr0: set ENOMEM, %o0
+.Lerr1: sethi %hi(errno), %g1
+ or %g1, %lo(errno), %g1
+#ifdef PIC
+ ldx [%l7+%g1], %g1
+ st %o0, [%g1]
+#else
+ st %o0, [%g4+%g1]
+#endif
+#ifdef _LIBC_REENTRANT
+ call __errno_location
+ mov %o0,%l1
+ st %l1, [%o0]
+#endif
+ sub %g0, 1, %i0
+ jmpl %i7+8, %g0
+ restore
+
+ .size __brk, .-__brk
+
+weak_alias (__brk, brk)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-_setjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-_setjmp.S
new file mode 100644
index 0000000000..4e6a2da560
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* _setjmp is in setjmp.S */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-setjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-setjmp.S
new file mode 100644
index 0000000000..1da848d2f1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-setjmp.S
@@ -0,0 +1 @@
+/* setjmp is in setjmp.S */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
new file mode 100644
index 0000000000..76d11bdd88
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
@@ -0,0 +1,90 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ 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. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <asm/errno.h>
+#include <asm/unistd.h>
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
+
+ .text
+ .align 4
+ .globl __libc_clone
+ .type __libc_clone,@function
+ .weak clone
+ .weak __clone
+ __clone = __libc_clone
+ clone = __libc_clone
+
+__libc_clone:
+ save %sp,-160,%sp
+
+ /* sanity check arguments */
+ brz,pn %i0, 99f
+ mov %i0, %l0 /* save fn */
+ brz,pn %i1, 99f
+ mov %i3, %l3 /* save arg */
+
+ /* Do the system call */
+ mov %i1, %o1
+ mov %i2, %o0
+ set __NR_clone, %g1
+ ta 0x11
+ bcs,pn %xcc, 99f
+ nop
+ brnz %o0, __thread_start
+ mov %o0, %i0
+ ret
+ restore
+99:
+#ifdef PIC
+ call 1f
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(99b-.)), %l7
+1: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(99b-.)), %l7
+ add %l7, %o7, %l7
+ set EINVAL, %i0
+ sethi %hi(errno), %g2
+ or %g2, %lo(errno), %g2
+ st %i0, [%l7+%g2]
+#else
+ sethi %hi(errno), %g2
+ add %g2, %g4, %g2
+ set EINVAL, %i0
+ st %i0, [%g2+%lo(errno)]
+#endif
+#ifdef _LIBC_REENTRANT
+ call __errno_location
+ nop
+ st %i0, [%o0]
+#endif
+ mov -1,%i0
+ ret
+ restore
+ .size __libc_clone, .-__libc_clone
+
+ .type __thread_start,@function
+__thread_start:
+ mov %g0, %fp /* terminate backtrace */
+ sub %sp, 6*8, %sp /* provide arg storage */
+ call %l0
+ mov %l3,%o0
+ call _exit,0
+ nop
+ .size __thread_start, .-__thread_start
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/fork.S b/sysdeps/unix/sysv/linux/sparc/sparc64/fork.S
new file mode 100644
index 0000000000..c735da5a44
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/fork.S
@@ -0,0 +1,33 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@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>
+
+PSEUDO (__libc_fork, fork, 0)
+ tst %o1
+ be %xcc, 1f
+ nop
+ /* child: return 0 */
+ clr %o0
+1: ret
+
+PSEUDO_END (__libc_fork)
+
+weak_alias (__libc_fork, __fork)
+weak_alias (__libc_fork, fork)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S b/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S
new file mode 100644
index 0000000000..05b06269e4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ 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>
+
+/* void getcontext(ucontext_t *); */
+
+ENTRY(__getcontext)
+
+ ta 0x6e
+ ret
+
+END(__getcontext)
+
+weak_alias(__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/gnu/types.h b/sysdeps/unix/sysv/linux/sparc/sparc64/gnu/types.h
new file mode 100644
index 0000000000..631a0d7824
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/gnu/types.h
@@ -0,0 +1,108 @@
+/* Copyright (C) 1991, 92, 94, 95, 96, 97 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. */
+
+#ifndef _GNU_TYPES_H
+#define _GNU_TYPES_H 1
+
+#include <features.h>
+
+/* Convenience types. */
+typedef unsigned char __u_char;
+typedef unsigned short int __u_short;
+typedef unsigned int __u_int;
+typedef unsigned long int __u_long;
+typedef unsigned long int __u_quad_t;
+typedef long int __quad_t;
+typedef signed char __int8_t;
+typedef unsigned char __uint8_t;
+typedef signed short int __int16_t;
+typedef unsigned short int __uint16_t;
+typedef signed int __int32_t;
+typedef unsigned int __uint32_t;
+typedef signed long int __int64_t;
+typedef unsigned long int __uint64_t;
+typedef __quad_t *__qaddr_t;
+
+typedef __u_long __dev_t; /* Type of device numbers. */
+typedef __u_int __uid_t; /* Type of user identifications. */
+typedef __u_int __gid_t; /* Type of group identifications. */
+typedef __u_long __ino_t; /* Type of file serial numbers. */
+typedef __u_int __mode_t; /* Type of file attribute bitmasks. */
+typedef __u_int __nlink_t; /* Type of file link counts. */
+typedef long int __off_t; /* Type of file sizes and offsets. */
+typedef __quad_t __loff_t; /* Type of file sizes and offsets. */
+typedef int __pid_t; /* Type of process identifications. */
+typedef long long int __ssize_t; /* Type of a byte count, or error. */
+typedef long int __rlim_t; /* Type of resource counts. */
+typedef long int __rlim64_t; /* Type of resource counts (LFS). */
+
+typedef struct
+ {
+ int __val[2];
+ } __fsid_t; /* Type of file system IDs. */
+
+/* Everythin' else. */
+typedef int __daddr_t; /* The type of a disk address. */
+typedef char *__caddr_t;
+typedef long int __time_t;
+typedef long int __swblk_t; /* Type of a swap block maybe? */
+
+typedef long int __clock_t;
+
+/* One element in the file descriptor mask array. */
+typedef unsigned long int __fd_mask;
+
+/* Due to incaution, we may have gotten these from a kernel header file. */
+#undef __FD_SETSIZE
+#undef __NFDBITS
+#undef __FDMASK
+
+/* Number of descriptors that can fit in an `fd_set'. */
+#define __FD_SETSIZE 1024
+
+/* It's easier to assume 8-bit bytes than to get CHAR_BIT. */
+#define __NFDBITS (8 * sizeof (__fd_mask))
+#define __FDELT(d) ((d) / __NFDBITS)
+#define __FDMASK(d) (1 << ((d) % __NFDBITS))
+
+/* fd_set for select and pselect. */
+typedef struct
+ {
+ /* XPG4.2 requires this member name. */
+ __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
+ } __fd_set;
+
+
+typedef int __key_t;
+
+
+/* Types from the Large File Support interface. */
+
+/* Type to count number os disk blocks. */
+typedef long int __blkcnt_t;
+typedef __quad_t __blkcnt64_t;
+
+/* Type to count file system blocks. */
+typedef unsigned int __fsblkcnt_t;
+typedef __u_quad_t __fsblkcnt64_t;
+
+/* Type to count file system inodes. */
+typedef unsigned long int __fsfilcnt_t;
+typedef __u_quad_t __fsfilcnt64_t;
+
+#endif /* gnu/types.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h b/sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h
new file mode 100644
index 0000000000..955714dc4f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h
@@ -0,0 +1,92 @@
+/* Prepare arguments for library initialization function.
+ 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. */
+
+/* The job of this fragment it to find argc and friends for INIT.
+ This is done in one of two ways: either in the stack context
+ of program start, or having dlopen pass them in. */
+
+#include <sysdep.h>
+
+#define __S1(x) #x
+#define __S(x) __S1(x)
+
+#ifdef PIC
+
+#define SYSDEP_CALL_INIT(NAME, INIT) asm("\
+ .weak _dl_starting_up
+ .global " #NAME "
+ .type " #NAME ",@function
+" #NAME ":
+ save %sp, -128, %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
+ ldx [%l7+%l2], %l2
+ brz,pn %l2, 3f
+ sethi %hi(__libc_multiple_libcs), %l3
+ ld [%l2], %l4
+ mov %g0, %l2
+ movrz %l4, 1, %l2
+3: or %l3, %lo(__libc_multiple_libcs), %l3
+ ldx [%l7+%l3], %l3
+ st %l2, [%l3]
+ /* If so, argc et al are in %o0-%o2 already. Otherwise, load them. */
+ brnz,pn %l2, " #INIT "
+ restore
+ ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0
+ add %sp, " __S(STACK_BIAS) "+23*8, %o1
+ sllx %o0, 3, %o2
+ add %o2, %o1, %o2
+ ba " #INIT "
+ add %o2, 8, %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
+ brz,pt %g2, 3f
+ sethi %hi(__libc_multiple_libcs), %g3
+ ld [%g4+%g2], %g1
+ mov %g0, %g2
+ movrz %g1, 1, %g2
+3: or %g3, %lo(__libc_multiple_libcs), %g3
+ st %g2, [%g3+%g4]
+ /* If so, argc et al are in %o0-%o2 already. Otherwise, load them. */
+ brnz,pn %g2, " #INIT "
+ nop
+ ldx [%sp+" __S(STACK_BIAS) "+22*8], %o0
+ add %sp, " __S(STACK_BIAS) "+23*8, %o1
+ sllx %o0, 3, %o2
+ add %o2, %o1, %o2
+ ba " #INIT "
+ add %o2, 8, %o2
+ .size "#NAME ", .-" #NAME);
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/jmp_buf.h b/sysdeps/unix/sysv/linux/sparc/sparc64/jmp_buf.h
new file mode 100644
index 0000000000..50c9965095
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/jmp_buf.h
@@ -0,0 +1,21 @@
+/* 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 <ucontext.h>
+
+typedef ucontext_t __jmp_buf[1];
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
new file mode 100644
index 0000000000..dd509a7e8a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
@@ -0,0 +1,22 @@
+/* Definition of `struct stat' used in the kernel */
+struct kernel_stat
+ {
+ unsigned int st_dev;
+ unsigned long int st_ino;
+ unsigned int st_mode;
+ short int st_nlink;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned int st_rdev;
+ long int st_size;
+ long int st_atime;
+ long int st_mtime;
+ long int st_ctime;
+ long int st_blksize;
+ long int st_blocks;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ };
+
+#define _HAVE___UNUSED1
+#define _HAVE___UNUSED2
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
new file mode 100644
index 0000000000..d63762cb15
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
@@ -0,0 +1,48 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ 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. */
+
+/* longjmp is implemented in terms of the setcontext trap on Linux/Sparc64. */
+
+#include <sysdep.h>
+
+/* Offsets into the jmp_buf structure. */
+
+#define O_mask_was_saved 512
+#define O_gregs 32
+#define O_g1 (O_gregs + 4*8)
+
+
+/* void longjmp (sigjmp_buf env, int val) */
+
+ENTRY(longjmp)
+
+ /* Modify the context with the value we want to return. */
+ movre %o1, 1, %o1
+ stx %o1, [%o0 + O_g1]
+
+ /* Let setcontext know if we want to modify the current sigmask. */
+ ld [%o0 + O_mask_was_saved], %o1
+
+ /* And bamf back to where we belong! */
+ ta 0x6f
+
+END(longjmp)
+
+strong_alias(longjmp, __longjmp)
+weak_alias(longjmp, _longjmp)
+weak_alias(longjmp, siglongjmp)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
new file mode 100644
index 0000000000..82ff4eae3c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
@@ -0,0 +1,37 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@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>
+
+ENTRY (__libc_pipe)
+ mov %o0, %o2 /* Save PIPEDES. */
+ LOADSYSCALL(pipe)
+ ta 0x11
+ bcc,pn %xcc, 2f
+ nop
+ SYSCALL_ERROR_HANDLER
+
+2: st %o0, [%o2] /* PIPEDES[0] = %o0; */
+ st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */
+ retl
+ clr %o0
+PSEUDO_END (__libc_pipe)
+
+weak_alias (__libc_pipe, __pipe)
+weak_alias (__libc_pipe, pipe)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h b/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h
new file mode 100644
index 0000000000..6a3f0a291a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h
@@ -0,0 +1,26 @@
+/* Low-level statistical profiling support function. Linux/Sparc64 version.
+ 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 <signal.h>
+
+void
+profil_counter (int signo, __siginfo_t *si)
+{
+ profil_count ((void *) si->si_regs.tpc);
+}
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S b/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S
new file mode 100644
index 0000000000..2968b65633
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S
@@ -0,0 +1,33 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ 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>
+
+
+/* void setcontext(ucontext_t *ctx); */
+.weak setcontext
+ENTRY(setcontext)
+
+ mov 1, %o1
+
+/* void __setcontext(ucontext_t *ctx, int restoremask); */
+ENTRY(__setcontext)
+
+ ta 0x6f
+
+END(__setcontext)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S
new file mode 100644
index 0000000000..65a1d34836
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S
@@ -0,0 +1,64 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ 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. */
+
+/* __sigsetjmp is implemented in terms of the getcontext trap on
+ Linux/Sparc64. */
+
+#include <sysdep.h>
+
+/* Offsets into the jmp_buf structure. */
+
+#define O_mask_was_saved 512
+#define O_gregs 32
+#define O_g1 (O_gregs + 4*8)
+
+/* int _setjmp(jmp_buf) */
+
+ENTRY(__setjmp)
+ ba __sigsetjmp_local
+ set 0, %o1
+END(__setjmp)
+
+/* int setjmp(jmp_buf) */
+
+ENTRY(setjmp)
+ set 1, %o1
+END(setjmp)
+
+/* int __sigsetjmp(jmp_buf, savemask) */
+
+ENTRY(__sigsetjmp)
+__sigsetjmp_local:
+
+ /* Record whether the user is intending to save the sigmask. */
+ st %o1, [%o0 + O_mask_was_saved]
+
+ /* Load up our return value, as longjmp is going to override
+ the jmp_buf on its way back. */
+ mov %g0, %g1
+
+ /* And call getcontext! */
+ ta 0x6e
+
+ retl
+ mov %g1, %o0
+
+END(__sigsetjmp)
+
+weak_alias(__setjmp, _setjmp)
+weak_extern(setjmp)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/sigjmp.S
new file mode 100644
index 0000000000..940ccbcf68
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigjmp.S
@@ -0,0 +1 @@
+/* There is no need for __sigjmp_save what with getcontext. */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/statfsbuf.h b/sysdeps/unix/sysv/linux/sparc/sparc64/statfsbuf.h
new file mode 100644
index 0000000000..9027eca2ac
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/statfsbuf.h
@@ -0,0 +1,42 @@
+/* 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. */
+
+/*
+ * Never include this file directly; use <sys/statfs.h> instead.
+ */
+
+#ifndef _BITS_STATFS_H
+#define _BITS_STATFS_H
+
+#include <bits/types.h> /* for __fsid_t */
+
+struct statfs
+ {
+ long int f_type;
+ long int f_bsize;
+ long int f_blocks;
+ long int f_bfree;
+ long int f_bavail;
+ long int f_files;
+ long int f_ffree;
+ __fsid_t f_fsid;
+ long int f_namelen;
+ long int f_spare[6];
+ };
+
+#endif /* bits/statfs.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
new file mode 100644
index 0000000000..30dace5903
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
@@ -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 <sysdep.h>
+ .text
+
+ENTRY (syscall)
+
+ mov %o0,%g1
+ mov %o1,%o0
+ mov %o2,%o1
+ mov %o3,%o2
+ mov %o4,%o3
+ mov %o5,%o4
+
+ ta 0x11
+
+ bcc,pt %xcc,1f
+ nop
+ SYSCALL_ERROR_HANDLER
+
+1: retl
+
+PSEUDO_END (syscall)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list b/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list
new file mode 100644
index 0000000000..d0bee8fa07
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list
@@ -0,0 +1,25 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+# Whee! 64-bit systems naturally implement llseek.
+llseek EXTRA lseek 3 llseek
+pread EXTRA pread 4 __pread pread __pread64 pread64
+pwrite EXTRA pwrite 4 __pwrite pwrite __pwrite64 pwrite64
+
+# Override select.S in parent directory:
+select - select 5 __select select
+accept - accept 3 __accept accept
+bind - bind 3 __bind bind
+connect - connect 3 __connect connect
+getpeername - getpeername 3 __getpeername getpeername
+getsockname - getsockname 3 __getsockname getsockname
+getsockopt - getsockopt 5 __getsockopt getsockopt
+listen - listen 2 __listen listen
+recv - recv 4 __recv recv
+recvfrom - recvfrom 6 __recvfrom recvfrom
+recvmsg - recvmsg 3 __recvmsg recvmsg
+send - send 4 __send send
+sendmsg - sendmsg 3 __sendmsg sendmsg
+sendto - sendto 6 __sendto sendto
+setsockopt - setsockopt 5 __setsockopt setsockopt
+shutdown - shutdown 2 __shutdown shutdown
+socketpair - socketpair 4 __socketpair socketpair
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.S b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.S
new file mode 100644
index 0000000000..736578083c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.S
@@ -0,0 +1,31 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ 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. */
+
+
+/* Define errno */
+
+ .section .bss
+ .globl errno
+ .align 2
+errno: .space 4
+ .type errno, @object
+ .size errno, 4
+
+ .globl __errno
+__errno = errno
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
new file mode 100644
index 0000000000..c880e4a2dc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
@@ -0,0 +1,138 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ 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. */
+
+#ifndef _LINUX_SPARC64_SYSDEP_H
+#define _LINUX_SPARC64_SYSDEP_H 1
+
+#include <sysdeps/unix/sysdep.h>
+
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+#ifdef ASSEMBLER
+
+#ifdef DONT_LOAD_G1
+# define LOADSYSCALL(x)
+#else
+# define LOADSYSCALL(x) mov __NR_##x, %g1
+#endif
+
+/* Linux/SPARC uses a different trap number */
+#undef PSEUDO
+#undef ENTRY
+
+#define ENTRY(name) \
+ .global C_SYMBOL_NAME(name); \
+ .align 2; \
+ C_LABEL(name); \
+ .type name,@function;
+
+#ifdef PIC
+# ifdef _LIBC_REENTRANT
+# define SYSCALL_ERROR_HANDLER \
+ .global C_SYMBOL_NAME(errno); \
+ .type C_SYMBOL_NAME(errno),@object; \
+ save %sp,-160,%sp; \
+ 101: call 102f; \
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(101b-.)),%g2; \
+ 102: or %g2,%lo(_GLOBAL_OFFSET_TABLE_-(101b-.)),%g2; \
+ sethi %hi(errno),%i1; \
+ add %g2,%o7,%l7; \
+ or %i1,%lo(errno),%i1; \
+ ldx [%l7+%i1],%g2; \
+ st %i0,[%g2]; \
+ call __errno_location; \
+ nop; \
+ st %i0,[%o0]; \
+ sub %g0,1,%i0; \
+ jmpl %i7+8, %g0; \
+ restore
+# else
+# define SYSCALL_ERROR_HANDLER \
+ .global C_SYMBOL_NAME(errno); \
+ .type C_SYMBOL_NAME(errno),@object; \
+ mov %o7,%g3; \
+ 101: call 102f; \
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(101b-.)),%g2; \
+ 102: or %g2,%lo(_GLOBAL_OFFSET_TABLE_-(101b-.)),%g2; \
+ sethi %hi(errno),%o1; \
+ add %g2,%o7,%l7; \
+ or %o1,%lo(errno),%o1; \
+ mov %g3,%o7; \
+ ldx [%l7+%o1],%g2; \
+ st %o0,[%g2]
+# endif
+#else
+# ifdef _LIBC_REENTRANT
+# define SYSCALL_ERROR_HANDLER \
+ .global C_SYMBOL_NAME(errno); \
+ .type C_SYMBOL_NAME(errno),@object; \
+ save %sp,-160,%sp; \
+ sethi %hi(errno),%g1; \
+ or %g1,%lo(errno),%g1; \
+ st %i0,[%g1+%g4]; \
+ call __errno_location; \
+ nop; \
+ st %i0,[%o0]; \
+ sub %g0,1,%i0; \
+ jmpl %i7+8, %g0; \
+ restore
+# else
+# define SYSCALL_ERROR_HANDLER \
+ .global C_SYMBOL_NAME(errno); \
+ .type C_SYMBOL_NAME(errno),@object; \
+ sethi %hi(errno),%g1; \
+ or %g1,%lo(errno),%g1; \
+ st %i0,[%g1+%g4]; \
+ retl; \
+ sub %g0,1,%i0
+# endif
+#endif
+
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY(name); \
+ LOADSYSCALL(syscall_name); \
+ ta 0x11; \
+ bcc,pt %xcc,1f; \
+ nop; \
+ SYSCALL_ERROR_HANDLER; \
+1:
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ .size name,.-name
+
+#undef END
+#define END(name) \
+ .size name,.-name
+
+/* Careful here! This "ret" define can interfere; use jmpl if unsure. */
+#define ret retl; nop
+#define r0 %o0
+#define r1 %o1
+#define MOVE(x,y) mov x, y
+
+#endif /* ASSEMBLER */
+
+/* This is the offset from the %sp to the backing store above the
+ register windows. So if you poke stack memory directly you add this. */
+#define STACK_BIAS 2047
+
+#endif /* linux/sparc64/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ucontext.h b/sysdeps/unix/sysv/linux/sparc/sparc64/ucontext.h
new file mode 100644
index 0000000000..160e2fc43a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ucontext.h
@@ -0,0 +1,67 @@
+#ifndef _UCONTEXT_H
+#define _UCONTEXT_H
+
+#include <signal.h>
+
+#define MC_TSTATE 0
+#define MC_PC 1
+#define MC_NPC 2
+#define MC_Y 3
+#define MC_G1 4
+#define MC_G2 5
+#define MC_G3 6
+#define MC_G4 7
+#define MC_G5 8
+#define MC_G6 9
+#define MC_G7 10
+#define MC_O0 11
+#define MC_O1 12
+#define MC_O2 13
+#define MC_O3 14
+#define MC_O4 15
+#define MC_O5 16
+#define MC_O6 17
+#define MC_O7 18
+#define MC_NGREG 19
+
+typedef unsigned long mc_greg_t;
+typedef mc_greg_t mc_gregset_t[MC_NGREG];
+
+#define MC_MAXFPQ 16
+struct mc_fq {
+ unsigned long *mcfq_addr;
+ unsigned int mcfq_insn;
+};
+
+struct mc_fpu {
+ union {
+ unsigned int sregs[32];
+ unsigned long dregs[32];
+ long double qregs[16];
+ } mcfpu_fregs;
+ unsigned long mcfpu_fsr;
+ unsigned long mcfpu_fprs;
+ unsigned long mcfpu_gsr;
+ struct mc_fq *mcfpu_fq;
+ unsigned char mcfpu_qcnt;
+ unsigned char mcfpu_qentsz;
+ unsigned char mcfpu_enab;
+};
+typedef struct mc_fpu mc_fpu_t;
+
+typedef struct {
+ mc_gregset_t mc_gregs;
+ mc_greg_t mc_fp;
+ mc_greg_t mc_i7;
+ mc_fpu_t mc_fpregs;
+} mcontext_t;
+
+struct ucontext {
+ struct ucontext *uc_link;
+ unsigned long uc_flags;
+ unsigned long uc_sigmask;
+ mcontext_t uc_mcontext;
+};
+typedef struct ucontext ucontext_t;
+
+#endif /* ucontext.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sys/kernel_termios.h b/sysdeps/unix/sysv/linux/sparc/sys/kernel_termios.h
new file mode 100644
index 0000000000..b33fd31128
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sys/kernel_termios.h
@@ -0,0 +1,20 @@
+#ifndef _SYS_KERNEL_TERMIOS_H
+#define _SYS_KERNEL_TERMIOS_H 1
+/* The following corresponds to the values from the Linux 2.1.20 kernel. */
+
+/* We need the definition of tcflag_t, cc_t, and speed_t. */
+#include <termbits.h>
+
+#define __KERNEL_NCCS 17
+
+struct __kernel_termios
+ {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[__KERNEL_NCCS]; /* control characters */
+ };
+
+#endif /* sys/kernel_termios.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sys/trap.h b/sysdeps/unix/sysv/linux/sparc/sys/trap.h
new file mode 100644
index 0000000000..99b9c60e06
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sys/trap.h
@@ -0,0 +1,7 @@
+/* Include Linux/SPARC specific trap definitions. */
+#ifndef _SYS_TRAP_H
+#define _SYS_TRAP_H 1
+
+#include <asm/traps.h>
+
+#endif /* sys/trap.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/termbits.h b/sysdeps/unix/sysv/linux/sparc/termbits.h
new file mode 100644
index 0000000000..33122d4723
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/termbits.h
@@ -0,0 +1,202 @@
+/* termios type and macro definitions. Linux/SPARC version.
+ Copyright (C) 1993, 1994, 1995, 1996, 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. */
+
+#ifndef _TERMBITS_H
+#define _TERMBITS_H 1
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 17
+struct termios
+ {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ };
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VEOL 5
+#define VEOL2 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VDSUSP 11 /* SunOS POSIX nicety I do believe... */
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+
+#define VMIN VEOF
+#define VTIME VEOL
+
+/* c_iflag bits */
+#define IGNBRK 0x00000001
+#define BRKINT 0x00000002
+#define IGNPAR 0x00000004
+#define PARMRK 0x00000008
+#define INPCK 0x00000010
+#define ISTRIP 0x00000020
+#define INLCR 0x00000040
+#define IGNCR 0x00000080
+#define ICRNL 0x00000100
+#define IUCLC 0x00000200
+#define IXON 0x00000400
+#define IXANY 0x00000800
+#define IXOFF 0x00001000
+#define IMAXBEL 0x00002000
+
+/* c_oflag bits */
+#define OPOST 0x00000001
+#define OLCUC 0x00000002
+#define ONLCR 0x00000004
+#define OCRNL 0x00000008
+#define ONOCR 0x00000010
+#define ONLRET 0x00000020
+#define OFILL 0x00000040
+#define OFDEL 0x00000080
+#define NLDLY 0x00000100
+#define NL0 0x00000000
+#define NL1 0x00000100
+#define CRDLY 0x00000600
+#define CR0 0x00000000
+#define CR1 0x00000200
+#define CR2 0x00000400
+#define CR3 0x00000600
+#define TABDLY 0x00001800
+#define TAB0 0x00000000
+#define TAB1 0x00000800
+#define TAB2 0x00001000
+#define TAB3 0x00001800
+#define XTABS 0x00001800
+#define BSDLY 0x00002000
+#define BS0 0x00000000
+#define BS1 0x00002000
+#define VTDLY 0x00004000
+#define VT0 0x00000000
+#define VT1 0x00004000
+#define FFDLY 0x00008000
+#define FF0 0x00000000
+#define FF1 0x00008000
+#define PAGEOUT 0x00010000 /* SUNOS specific */
+#define WRAP 0x00020000 /* SUNOS specific */
+
+/* c_cflag bit meaning */
+#define CBAUD 0x0000100f
+#define B0 0x00000000 /* hang up */
+#define B50 0x00000001
+#define B75 0x00000002
+#define B110 0x00000003
+#define B134 0x00000004
+#define B150 0x00000005
+#define B200 0x00000006
+#define B300 0x00000007
+#define B600 0x00000008
+#define B1200 0x00000009
+#define B1800 0x0000000a
+#define B2400 0x0000000b
+#define B4800 0x0000000c
+#define B9600 0x0000000d
+#define B19200 0x0000000e
+#define B38400 0x0000000f
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0x00000030
+#define CS5 0x00000000
+#define CS6 0x00000010
+#define CS7 0x00000020
+#define CS8 0x00000030
+#define CSTOPB 0x00000040
+#define CREAD 0x00000080
+#define PARENB 0x00000100
+#define PARODD 0x00000200
+#define HUPCL 0x00000400
+#define CLOCAL 0x00000800
+#define CBAUDEX 0x00001000
+#define B57600 0x00001001
+#define B76800 0x00001005
+#define B115200 0x00001002
+#define B230400 0x00001003
+#define B460800 0x00001004
+#define CIBAUD 0x100f0000 /* input baud rate (not used) */
+#define CMSPAR 0x40000000 /* mark or space (stick) parity */
+#define CRTSCTS 0x80000000 /* flow control */
+
+/* c_lflag bits */
+#define ISIG 0x00000001
+#define ICANON 0x00000002
+#define XCASE 0x00000004
+#define ECHO 0x00000008
+#define ECHOE 0x00000010
+#define ECHOK 0x00000020
+#define ECHONL 0x00000040
+#define NOFLSH 0x00000080
+#define TOSTOP 0x00000100
+#define ECHOCTL 0x00000200
+#define ECHOPRT 0x00000400
+#define ECHOKE 0x00000800
+#define DEFECHO 0x00001000 /* SUNOS thing, what is it? */
+#define FLUSHO 0x00002000
+#define PENDIN 0x00004000
+#define IEXTEN 0x00008000
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif