summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2000-02-23 16:43:43 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2000-02-23 16:43:43 +0000
commitc6d914d4fd5747b27e7e8b32f344295dfe2ab192 (patch)
tree396037b8e3ca4e9c55cc7d5c8166128d306730c7
parentee897edd394fbd5ad60e91c0c16f4b466607c6a5 (diff)
if we discover we are on a v8 cpu, and thus have the multiply and divide
instructions, replace the .{u,}{mul,div,rem} functions at runtime with (much smaller and faster) blocks using the actual hardware instructions.
-rw-r--r--sys/arch/sparc/sparc/cpu.c56
-rw-r--r--sys/arch/sparc/sparc/locore.s40
2 files changed, 72 insertions, 24 deletions
diff --git a/sys/arch/sparc/sparc/cpu.c b/sys/arch/sparc/sparc/cpu.c
index 677b30feb9c..0f3f42acb9a 100644
--- a/sys/arch/sparc/sparc/cpu.c
+++ b/sys/arch/sparc/sparc/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.30 2000/02/21 21:05:59 art Exp $ */
+/* $OpenBSD: cpu.c,v 1.31 2000/02/23 16:43:41 deraadt Exp $ */
/* $NetBSD: cpu.c,v 1.56 1997/09/15 20:52:36 pk Exp $ */
/*
@@ -1324,30 +1324,46 @@ fsrtoname(impl, vers, fver, buf)
return (buf);
}
+/*
+ * Whack the slow sun4/sun4c {,u}{mul,div,rem} functions with
+ * fast V8 ones
+ * We are called once before pmap_bootstrap and once after. We only do stuff
+ * in the "before" case. We happen to know that the kernel text is not
+ * write-protected then.
+ * XXX - investigate cache flushing, right now we can't do it because the
+ * flushes try to do va -> pa conversions.
+ */
+extern int _mulreplace, _mulreplace_end, _mul;
+extern int _umulreplace, _umulreplace_end, _umul;
+extern int _divreplace, _divreplace_end, _div;
+extern int _udivreplace, _udivreplace_end, _udiv;
+extern int _remreplace, _remreplace_end, _rem;
+extern int _uremreplace, _uremreplace_end, _urem;
+
+struct replace {
+ void *from, *frome, *to;
+} ireplace[] = {
+ { &_mulreplace, &_mulreplace_end, &_mul },
+ { &_umulreplace, &_umulreplace_end, &_umul },
+ { &_divreplace, &_divreplace_end, &_div },
+ { &_udivreplace, &_udivreplace_end, &_udiv },
+ { &_remreplace, &_remreplace_end, &_rem },
+ { &_uremreplace, &_uremreplace_end, &_urem },
+};
+
void
replacemul()
{
- extern char *_umulreplace, *_umulreplace_end;
- extern char *_mulreplace, *_mulreplace_end;
- extern char *_mul, *_umul;
- int i, j, s;
+ static int replacedone = 0;
+ int i, s;
- return;
+ if (replacedone)
+ return;
+ replacedone = 1;
- /*
- * Whack the slow sun4/sun4c umul/mul functions with
- * fast V8 ones
- */
s = splhigh();
- cpuinfo.cache_flush_all();
- for (i = 0; i < _umulreplace_end - _umulreplace; i++) {
- j = _umulreplace[i];
- pmap_writetext(&_umul[i], j);
- }
- for (i = 0; i < _mulreplace_end - _mulreplace; i++) {
- j = _mulreplace[i];
- pmap_writetext(&_mul[i], j);
- }
- cpuinfo.cache_flush_all();
+ for (i = 0; i < sizeof(ireplace)/sizeof(ireplace[0]); i++)
+ bcopy(ireplace[i].from, ireplace[i].to,
+ ireplace[i].frome - ireplace[i].from);
splx(s);
}
diff --git a/sys/arch/sparc/sparc/locore.s b/sys/arch/sparc/sparc/locore.s
index 6c153ab457d..f52137a6139 100644
--- a/sys/arch/sparc/sparc/locore.s
+++ b/sys/arch/sparc/sparc/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.35 2000/02/22 19:28:00 deraadt Exp $ */
+/* $OpenBSD: locore.s,v 1.36 2000/02/23 16:43:42 deraadt Exp $ */
/* $NetBSD: locore.s,v 1.73 1997/09/13 20:36:48 pk Exp $ */
/*
@@ -5918,20 +5918,52 @@ ENTRY(ffs)
add %o0, 24, %o0
/*
- * V8 sparc mul/umul replacements.
+ * V8 sparc {,u}{mul,div,rem} replacements.
*/
.globl __mulreplace, __mulreplace_end
__mulreplace:
retl
- smul %o0, %o1, %o0
+ smulcc %o0, %o1, %o0
__mulreplace_end:
.globl __umulreplace, __umulreplace_end
__umulreplace:
retl
- umul %o0, %o1, %o0
+ umulcc %o0, %o1, %o0
__umulreplace_end:
+.globl __divreplace, __divreplace_end
+__divreplace:
+ mov %g0, %y
+ retl
+ sdivcc %o0, %o1, %o0
+__divreplace_end:
+
+.globl __udivreplace, __udivreplace_end
+__udivreplace:
+ mov %g0, %y
+ retl
+ udivcc %o0, %o1, %o0
+__udivreplace_end:
+
+.globl __remreplace, __remreplace_end
+__remreplace:
+ mov %g0, %y
+ sdiv %o0, %o1, %o2
+ smul %o1, %o2, %o2
+ retl
+ subcc %o0, %o2, %o0
+__remreplace_end:
+
+.globl __uremreplace, __uremreplace_end
+__uremreplace:
+ mov %g0, %y
+ udiv %o0, %o1, %o2
+ umul %o1, %o2, %o2
+ retl
+ subcc %o0, %o2, %o0
+__uremreplace_end:
+
/*
* Signed multiply, from Appendix E of the Sparc Version 8
* Architecture Manual.