diff options
-rw-r--r-- | libexec/ld.so/sparc/Makefile.inc | 6 | ||||
-rw-r--r-- | libexec/ld.so/sparc/archdep.h | 10 | ||||
-rw-r--r-- | libexec/ld.so/sparc/ldasm.S | 78 | ||||
-rw-r--r-- | libexec/ld.so/sparc/rtld_machine.c | 82 | ||||
-rw-r--r-- | libexec/ld.so/sparc/syscall.h | 4 |
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) { |