summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libexec/ld.so/sparc/Makefile.inc6
-rw-r--r--libexec/ld.so/sparc/archdep.h10
-rw-r--r--libexec/ld.so/sparc/ldasm.S78
-rw-r--r--libexec/ld.so/sparc/rtld_machine.c82
-rw-r--r--libexec/ld.so/sparc/syscall.h4
5 files changed, 172 insertions, 8 deletions
diff --git a/libexec/ld.so/sparc/Makefile.inc b/libexec/ld.so/sparc/Makefile.inc
index 39fecb8b1e2..04e7d2913e0 100644
--- a/libexec/ld.so/sparc/Makefile.inc
+++ b/libexec/ld.so/sparc/Makefile.inc
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile.inc,v 1.1 2002/08/21 15:40:30 art Exp $
+# $OpenBSD: Makefile.inc,v 1.2 2002/11/23 19:14:25 drahn Exp $
CFLAGS += -fpic -msoft-float -I${LIBCSRCDIR}/arch/sparc
-AFLAGS = ${CFLAGS}
+AFLAGS = ${CFLAGS} -DSTRONG_SPARC
LIBCSRCDIR=${.CURDIR}/../../lib/libc
.include "${LIBCSRCDIR}/arch/sparc/Makefile.inc"
.PATH: ${LIBCSRCDIR}/arch/sparc/gen/
-SRCS+=umul.S
+SRCS+=umul.S mul.S
diff --git a/libexec/ld.so/sparc/archdep.h b/libexec/ld.so/sparc/archdep.h
index 4191ba5f7d2..8fb7135a6e3 100644
--- a/libexec/ld.so/sparc/archdep.h
+++ b/libexec/ld.so/sparc/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.4 2002/10/25 10:39:52 pefo Exp $ */
+/* $OpenBSD: archdep.h,v 1.5 2002/11/23 19:14:25 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -77,6 +77,12 @@ RELOC_RELA(Elf_RelA *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
}
}
-#define RELOC_GOT(obj, offs)
+/*
+ * this is not necessary for sparc, but can be used as a hook
+ * to insert the mul,umul,... optimization for newer sparcs.
+ */
+#define RELOC_GOT(obj, offs) _dl_mul_fixup()
+void _dl_mul_fixup(void);
+
#endif /* _SPARC_ARCHDEP_H_ */
diff --git a/libexec/ld.so/sparc/ldasm.S b/libexec/ld.so/sparc/ldasm.S
index 3ff5601e76a..38c2259303f 100644
--- a/libexec/ld.so/sparc/ldasm.S
+++ b/libexec/ld.so/sparc/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.7 2002/11/22 23:58:09 drahn Exp $ */
+/* $OpenBSD: ldasm.S,v 1.8 2002/11/23 19:14:25 drahn Exp $ */
/*
* Copyright (c) 2001 Jason L. Wright (jason@thought.net)
@@ -280,3 +280,79 @@ _dl_getdirentries:
retl
sub %g0, %o0, %o0 ! error: result = -errno
+
+ .section ".text"
+ .align 4
+ .globl _dl_sysctl
+ .type _dl_sysctl,@function
+_dl_sysctl:
+ mov SYS___sysctl | SYSCALL_G2RFLAG, %g1 ! call sys_fstat
+ add %o7, 8, %g2 ! just return on success
+ t ST_SYSCALL ! off to wonderland
+ retl
+ sub %g0, %o0, %o0 ! error: result = -errno
+
+/*
+ * V8 sparc .{,u}{mul,div,rem} replacements.
+ * We try to mimic them 100%. Full 64 bit sources or outputs, and
+ * these routines are required to update the condition codes.
+ */
+.globl _C_LABEL(_mulreplace), _C_LABEL(_mulreplace_end)
+_C_LABEL(_mulreplace):
+ smulcc %o0, %o1, %o0
+ retl
+ rd %y, %o1
+_C_LABEL(_mulreplace_end):
+
+.globl _C_LABEL(_umulreplace), _C_LABEL(_umulreplace_end)
+_C_LABEL(_umulreplace):
+ umulcc %o0, %o1, %o0
+ retl
+ rd %y, %o1
+_C_LABEL(_umulreplace_end):
+
+.globl _C_LABEL(_divreplace), _C_LABEL(_divreplace_end)
+_C_LABEL(_divreplace):
+ sra %o0, 31, %g1
+ wr %g1, 0, %y
+ nop
+ nop
+ nop
+ retl
+ sdivcc %o0, %o1, %o0
+_C_LABEL(_divreplace_end):
+
+.globl _C_LABEL(_udivreplace), _C_LABEL(_udivreplace_end)
+_C_LABEL(_udivreplace):
+ wr %g0, 0, %y
+ nop
+ nop
+ nop
+ retl
+ udivcc %o0, %o1, %o0
+_C_LABEL(_udivreplace_end):
+
+.globl _C_LABEL(_remreplace), _C_LABEL(_remreplace_end)
+_C_LABEL(_remreplace):
+ sra %o0, 31, %g1
+ wr %g1, 0, %y
+ nop
+ nop
+ nop
+ sdiv %o0, %o1, %o2
+ smul %o1, %o2, %o2
+ retl
+ subcc %o0, %o2, %o0
+_C_LABEL(_remreplace_end):
+
+.globl _C_LABEL(_uremreplace), _C_LABEL(_uremreplace_end)
+_C_LABEL(_uremreplace):
+ wr %g0, 0, %y
+ nop
+ nop
+ nop
+ udiv %o0, %o1, %o2
+ umul %o1, %o2, %o2
+ retl
+ subcc %o0, %o2, %o0
+_C_LABEL(_uremreplace_end):
diff --git a/libexec/ld.so/sparc/rtld_machine.c b/libexec/ld.so/sparc/rtld_machine.c
index d92ede5ad01..73ccd4ffc3b 100644
--- a/libexec/ld.so/sparc/rtld_machine.c
+++ b/libexec/ld.so/sparc/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.9 2002/11/14 15:15:54 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.10 2002/11/23 19:14:25 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -38,6 +38,9 @@
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <machine/cpu.h>
#include <nlist.h>
#include <link.h>
@@ -396,3 +399,80 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
}
}
+
+
+void __mul(void);
+void _mulreplace_end(void);
+void _mulreplace(void);
+void __umul(void);
+void _umulreplace_end(void);
+void _umulreplace(void);
+
+void __div(void);
+void _divreplace_end(void);
+void _divreplace(void);
+void __udiv(void);
+void _udivreplace_end(void);
+void _udivreplace(void);
+
+void __rem(void);
+void _remreplace_end(void);
+void _remreplace(void);
+void __urem(void);
+void _uremreplace_end(void);
+void _uremreplace(void);
+
+void
+_dl_mul_fixup()
+{
+ int mib[2], v8mul;
+ size_t len;
+
+
+ mib[0] = CTL_MACHDEP;
+ mib[1] = CPU_V8MUL;
+ len = sizeof(v8mul);
+ _dl_sysctl(mib, 2, &v8mul, &len, NULL, 0);
+
+
+ if (!v8mul)
+ return;
+
+ _dl_mprotect(&__mul, _mulreplace_end-_mulreplace,
+ PROT_READ|PROT_WRITE|PROT_EXEC);
+ _dl_bcopy(_mulreplace, __mul, _mulreplace_end-_mulreplace);
+ _dl_mprotect(&__mul, _mulreplace_end-_mulreplace,
+ PROT_READ|PROT_EXEC);
+
+ _dl_mprotect(&__umul, _umulreplace_end-_umulreplace,
+ PROT_READ|PROT_WRITE|PROT_EXEC);
+ _dl_bcopy(_umulreplace, __umul, _umulreplace_end-_umulreplace);
+ _dl_mprotect(&__umul, _umulreplace_end-_umulreplace,
+ PROT_READ|PROT_EXEC);
+
+
+ _dl_mprotect(&__div, _divreplace_end-_divreplace,
+ PROT_READ|PROT_WRITE|PROT_EXEC);
+ _dl_bcopy(_divreplace, __div, _divreplace_end-_divreplace);
+ _dl_mprotect(&__div, _divreplace_end-_divreplace,
+ PROT_READ|PROT_EXEC);
+
+ _dl_mprotect(&__udiv, _udivreplace_end-_udivreplace,
+ PROT_READ|PROT_WRITE|PROT_EXEC);
+ _dl_bcopy(_udivreplace, __udiv, _udivreplace_end-_udivreplace);
+ _dl_mprotect(&__udiv, _udivreplace_end-_udivreplace,
+ PROT_READ|PROT_EXEC);
+
+
+ _dl_mprotect(&__rem, _remreplace_end-_remreplace,
+ PROT_READ|PROT_WRITE|PROT_EXEC);
+ _dl_bcopy(_remreplace, __rem, _remreplace_end-_remreplace);
+ _dl_mprotect(&__rem, _remreplace_end-_remreplace,
+ PROT_READ|PROT_EXEC);
+
+ _dl_mprotect(&__urem, _uremreplace_end-_uremreplace,
+ PROT_READ|PROT_WRITE|PROT_EXEC);
+ _dl_bcopy(_uremreplace, __urem, _uremreplace_end-_uremreplace);
+ _dl_mprotect(&__urem, _uremreplace_end-_uremreplace,
+ PROT_READ|PROT_EXEC);
+}
diff --git a/libexec/ld.so/sparc/syscall.h b/libexec/ld.so/sparc/syscall.h
index 3d450ad5e99..c11613b6120 100644
--- a/libexec/ld.so/sparc/syscall.h
+++ b/libexec/ld.so/sparc/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.1 2002/07/27 13:19:26 art Exp $ */
+/* $OpenBSD: syscall.h,v 1.2 2002/11/23 19:14:25 drahn Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -58,6 +58,8 @@ int _dl_fstat(int, struct stat *);
int _dl_fcntl(int, int, ...);
int _dl_getdirentries(int, char*, int, long *);
+int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
{