diff options
-rw-r--r-- | sys/arch/sparc/sparc/cpu.c | 56 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/locore.s | 40 |
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. |