diff options
author | jwadams <none@none> | 2005-09-15 17:17:44 -0700 |
---|---|---|
committer | jwadams <none@none> | 2005-09-15 17:17:44 -0700 |
commit | 4eb5116a772d340fe75c795059e1566c07b9994c (patch) | |
tree | 5975f4570cb6c8d589b5243b93f35364bb248eff /usr/src/lib/libc/sparc | |
parent | 562eee46592ccd6ead143e8a4ad19d9a5d8f9c3a (diff) | |
download | illumos-gate-4eb5116a772d340fe75c795059e1566c07b9994c.tar.gz |
6324631 sparc hwmuldiv support should be in libc
--HG--
rename : usr/src/lib/libc/sparc/crt/divrem64.c => deleted_files/usr/src/lib/libc/sparc/crt/divrem64.c
rename : usr/src/lib/libc/sparc/crt/mul64.c => deleted_files/usr/src/lib/libc/sparc/crt/mul64.c
rename : usr/src/lib/libc/sparc/crt/muldiv64.il => deleted_files/usr/src/lib/libc/sparc/crt/muldiv64.il
rename : usr/src/lib/libc_psr/sun4u/common/hwmuldiv.s => deleted_files/usr/src/lib/libc_psr/sun4u/common/hwmuldiv.s
Diffstat (limited to 'usr/src/lib/libc/sparc')
-rw-r--r-- | usr/src/lib/libc/sparc/Makefile | 11 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/crt/divrem64.c | 404 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/crt/hwmuldiv.s | 79 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/crt/mul64.c | 89 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/crt/muldiv64.il | 43 |
5 files changed, 78 insertions, 548 deletions
diff --git a/usr/src/lib/libc/sparc/Makefile b/usr/src/lib/libc/sparc/Makefile index 78b46b2c31..3f4cae59ae 100644 --- a/usr/src/lib/libc/sparc/Makefile +++ b/usr/src/lib/libc/sparc/Makefile @@ -48,9 +48,7 @@ CRTOBJS= \ _ftou.o \ cerror.o \ cerror64.o \ - divrem64.o \ - hwmuldiv.o \ - mul64.o + hwmuldiv.o DYNOBJS= @@ -1006,8 +1004,6 @@ SRCS= \ $(UNWINDMACHOBJS:%.o=../port/unwind/%.c) \ $(FPOBJS:%.o=../$(MACH)/fp/%.c) \ $(LIBCBASE)/crt/_ftou.c \ - $(LIBCBASE)/crt/divrem64.c \ - $(LIBCBASE)/crt/mul64.c \ $(LIBCBASE)/gen/_xregs_clrptr.c \ $(LIBCBASE)/gen/ecvt.c \ $(LIBCBASE)/gen/getctxt.c \ @@ -1095,10 +1091,6 @@ $(QIL:%=pics/%) := CFLAGS += ../$(MACH)/fp/__quad.il pics/_Q%.o := sparc_COPTFLAG = -xO4 -dalign pics/__quad%.o := sparc_COPTFLAG = -xO4 -dalign -# Files in crt subdirectory which need muldiv64.il inline template -CIL= mul64.o divrem64.o -$(CIL:%=pics/%) := CFLAGS += $(LIBCBASE)/crt/muldiv64.il - # large-file-aware components that should be built large $(COMSYSOBJS64:%=pics/%) := \ @@ -1159,7 +1151,6 @@ $(LINTLIB):= LINTFLAGS=-nvx $(TIL:%=pics/%): $(LIBCBASE)/threads/sparc.il $(IL:%=pics/%): $(LIBCBASE)/fp/base.il $(QIL:%=pics/%): ../$(MACH)/fp/__quad.il -$(CIL:%=pics/%): $(LIBCBASE)/crt/muldiv64.il # include common libc targets include ../Makefile.targ diff --git a/usr/src/lib/libc/sparc/crt/divrem64.c b/usr/src/lib/libc/sparc/crt/divrem64.c deleted file mode 100644 index 9fbdab1055..0000000000 --- a/usr/src/lib/libc/sparc/crt/divrem64.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1991-1997, by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "synonyms.h" - -/* - * These routines are to support the compiler run-time only, and - * should NOT be called directly from C! - */ - -#define W 64 /* bits in a word */ -#define B 4 /* number base of division (must be a power of 2) */ -#define N 2 /* log2(B) */ -#define WB (W/N) /* base B digits in a word */ -#define Q dividend /* re-use the dividend as the partial quotient */ -#define Big_value (1ull<<(W-N-1)) /* (B ^ WB-1)/2 */ - -/* - * An 'inline' routine that does a 'ta 2' to simulate the effects of - * a hardware divide-by-zero. - */ -extern long long __raise_divide_by_zero(void); - -long long -__div64(long long dividend, long long divisor) -{ - long long R; /* partial remainder */ - unsigned long long V; /* multiple of the divisor */ - int iter, sign = 0; - - if (divisor == 0) - return (__raise_divide_by_zero()); - if (dividend < 0) { - dividend = -dividend; - sign = 1; - } - if (divisor < 0) { - divisor = -divisor; - sign ^= 1; - } - - /* - * -(-2^63) == -2^63, so compare unsigned long long, so that - * -2^63 as divisor, or -2^63 as dividend, works. - */ - if (dividend < (unsigned long long)divisor) - return ((long long)0); - - if (!((unsigned)(dividend >> 32) | (unsigned)(divisor >> 32))) { - Q = (unsigned long long)((unsigned)dividend/(unsigned)divisor); - goto ret; - } - - R = dividend; - V = divisor; - iter = 0; - if (R >= Big_value) { - int SC; - - for (; V < Big_value; iter++) - V <<= N; - for (SC = 0; V < R; SC++) { - if ((long long)V < 0) - break; - V <<= 1; - } - R -= V; - Q = 1; - while (--SC >= 0) { - Q <<= 1; - V >>= 1; - if (R >= 0) { - R -= V; - Q += 1; - } else { - R += V; - Q -= 1; - } - } - } else { - Q = 0; - do { - V <<= N; - iter++; - } while (V <= R); - } - - while (--iter >= 0) { - Q <<= N; - /* N-deep, B-wide decision tree */ - V >>= 1; - if (R >= 0) { - R -= V; - V >>= 1; - if (R >= 0) { - R -= V; - Q += 3; - } else { - R += V; - Q += 1; - } - } else { - R += V; - V >>= 1; - if (R >= 0) { - R -= V; - Q -= 1; - } else { - R += V; - Q -= 3; - } - } - } - if (R < 0) - Q -= 1; -ret: - return (sign ? -Q : Q); -} - -long long -__rem64(long long dividend, long long divisor) -{ - long long R; /* partial remainder */ - unsigned long long V; /* multiple of the divisor */ - int iter, sign = 0; - - if (divisor == 0) - return (__raise_divide_by_zero()); - if (dividend < 0) { - dividend = -dividend; - sign = 1; - } - if (divisor < 0) - divisor = -divisor; - - /* - * -(-2^63) == -2^63, so compare unsigned long long so that - * x % -2^63 works. - */ - if ((unsigned long long)divisor == 1) - return ((long long)0); - - /* Compare unsigned long long, so that -2^63 % x works. */ - if ((unsigned long long)dividend < divisor) { - R = dividend; - goto ret; - } - if (!((unsigned)(dividend >> 32) | (unsigned)(divisor >> 32))) { - R = (unsigned long long)((unsigned)dividend%(unsigned)divisor); - goto ret; - } - - R = dividend; - V = divisor; - iter = 0; - if (R >= Big_value) { - int SC; - - for (; V < Big_value; iter++) - V <<= N; - for (SC = 0; V < R; SC++) { - if ((long long)V < 0) - break; - V <<= 1; - } - R -= V; - Q = 1; - while (--SC >= 0) { - Q <<= 1; - V >>= 1; - if (R >= 0) { - R -= V; - Q += 1; - } else { - R += V; - Q -= 1; - } - } - } else { - Q = 0; - do { - V <<= N; - iter++; - } while (V <= R); - } - - while (--iter >= 0) { - Q <<= N; - /* N-deep, B-wide decision tree */ - V >>= 1; - if (R >= 0) { - R -= V; - V >>= 1; - if (R >= 0) { - R -= V; - Q += 3; - } else { - R += V; - Q += 1; - } - } else { - R += V; - V >>= 1; - if (R >= 0) { - R -= V; - Q -= 1; - } else { - R += V; - Q -= 3; - } - } - } - if (R < 0) - R += divisor; -ret: - return (sign ? -R : R); -} - -unsigned long long -__udiv64(unsigned long long dividend, unsigned long long divisor) -{ - long long R; /* partial remainder */ - unsigned long long V; /* multiple of the divisor */ - int iter; - - if (divisor == 0) - return (__raise_divide_by_zero()); - if (dividend < divisor) - return ((unsigned long long)0); - if (!((unsigned)(dividend >> 32) | (unsigned)(divisor >> 32))) - return ((unsigned long long) - ((unsigned)dividend/(unsigned)divisor)); - - R = dividend; - V = divisor; - iter = 0; - if (R >= Big_value) { - int SC; - - for (; V < Big_value; iter++) - V <<= N; - for (SC = 0; V < R; SC++) { - if ((long long)V < 0) - break; - V <<= 1; - } - R -= V; - Q = 1; - while (--SC >= 0) { - Q <<= 1; - V >>= 1; - if (R >= 0) { - R -= V; - Q += 1; - } else { - R += V; - Q -= 1; - } - } - } else { - Q = 0; - do { - V <<= N; - iter++; - } while (V <= R); - } - - while (--iter >= 0) { - Q <<= N; - /* N-deep, B-wide decision tree */ - V >>= 1; - if (R >= 0) { - R -= V; - V >>= 1; - if (R >= 0) { - R -= V; - Q += 3; - } else { - R += V; - Q += 1; - } - } else { - R += V; - V >>= 1; - if (R >= 0) { - R -= V; - Q -= 1; - } else { - R += V; - Q -= 3; - } - } - } - if (R < 0) - Q -= 1; - return (Q); -} - -unsigned long long -__urem64(unsigned long long dividend, unsigned long long divisor) -{ - long long R; /* parital remainder */ - unsigned long long V; /* multiple of the divisor */ - int iter; - - if (divisor == 0) - return (__raise_divide_by_zero()); - else if (divisor == 1) - return ((unsigned long long)0); - if (dividend < divisor) - return (dividend); - if (!((unsigned)(dividend >> 32) | (unsigned)(divisor >> 32))) - return ((unsigned long long) - ((unsigned)dividend%(unsigned)divisor)); - - R = dividend; - V = divisor; - iter = 0; - if (R >= Big_value) { - int SC; - - for (; V < Big_value; iter++) - V <<= N; - for (SC = 0; V < R; SC++) { - if ((long long)V < 0) - break; - V <<= 1; - } - R -= V; - Q = 1; - while (--SC >= 0) { - Q <<= 1; - V >>= 1; - if (R >= 0) { - R -= V; - Q += 1; - } else { - R += V; - Q -= 1; - } - } - } else { - Q = 0; - do { - V <<= N; - iter++; - } while (V <= R); - } - - while (--iter >= 0) { - Q <<= N; - /* N-deep, B-wide decision tree */ - V >>= 1; - if (R >= 0) { - R -= V; - V >>= 1; - if (R >= 0) { - R -= V; - Q += 3; - } else { - R += V; - Q += 1; - } - } else { - R += V; - V >>= 1; - if (R >= 0) { - R -= V; - Q -= 1; - } else { - R += V; - Q -= 3; - } - } - } - if (R < 0) - R += divisor; - return (R); -} diff --git a/usr/src/lib/libc/sparc/crt/hwmuldiv.s b/usr/src/lib/libc/sparc/crt/hwmuldiv.s index 2d2a08e848..0a83278017 100644 --- a/usr/src/lib/libc/sparc/crt/hwmuldiv.s +++ b/usr/src/lib/libc/sparc/crt/hwmuldiv.s @@ -20,8 +20,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1994-2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -95,3 +95,78 @@ retl sub %o0, %o2, %o0 SET_SIZE(.urem) + +/* + * v8plus versions of __{u,}{mul,div,rem}64 compiler support routines + */ + +/* + * Convert 32-bit arg pairs in %o0:o1 and %o2:%o3 to 64-bit args in %o1 and %o2 + */ +#define ARGS_TO_64 \ + sllx %o0, 32, %o0; \ + srl %o1, 0, %o1; \ + sllx %o2, 32, %o2; \ + srl %o3, 0, %o3; \ + or %o0, %o1, %o1; \ + or %o2, %o3, %o2 + +! +! division, signed +! + ENTRY(__div64) + ARGS_TO_64 + sdivx %o1, %o2, %o1 + retl + srax %o1, 32, %o0 + SET_SIZE(__div64) + +! +! division, unsigned +! + ENTRY(__udiv64) + ARGS_TO_64 + udivx %o1, %o2, %o1 + retl + srax %o1, 32, %o0 + SET_SIZE(__udiv64) + +! +! multiplication, signed and unsigned +! + ENTRY(__mul64) + ALTENTRY(__umul64) + ARGS_TO_64 + sub %o1, %o2, %o0 ! %o0 = a - b + movrlz %o0, %g0, %o0 ! %o0 = (a < b) ? 0 : a - b + sub %o1, %o0, %o1 ! %o1 = (a < b) ? a : b = min(a, b) + add %o2, %o0, %o2 ! %o2 = (a < b) ? b : a = max(a, b) + mulx %o1, %o2, %o1 ! min(a, b) in "rs1" for early exit + retl + srax %o1, 32, %o0 + SET_SIZE(__mul64) + SET_SIZE(__umul64) + +! +! unsigned remainder +! + ENTRY(__urem64) + ARGS_TO_64 + udivx %o1, %o2, %o3 + mulx %o3, %o2, %o3 + sub %o1, %o3, %o1 + retl + srax %o1, 32, %o0 + SET_SIZE(__urem64) + +! +! signed remainder +! + ENTRY(__rem64) + ARGS_TO_64 + sdivx %o1, %o2, %o3 + mulx %o2, %o3, %o3 + sub %o1, %o3, %o1 + retl + srax %o1, 32, %o0 + SET_SIZE(__rem64) diff --git a/usr/src/lib/libc/sparc/crt/mul64.c b/usr/src/lib/libc/sparc/crt/mul64.c deleted file mode 100644 index 16b10f1fec..0000000000 --- a/usr/src/lib/libc/sparc/crt/mul64.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1991-1997, by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "synonyms.h" - -/* - * These routines are to support the compiler run-time only, and - * should NOT be called directly from C! - */ - -extern unsigned long long __umul32x32to64(unsigned, unsigned); - -long long -__mul64(long long i, long long j) -{ - unsigned i0, i1, j0, j1; - int sign = 0; - long long result = 0; - - if (i < 0) { - i = -i; - sign = 1; - } - if (j < 0) { - j = -j; - sign ^= 1; - } - - i1 = (unsigned)i; - j0 = j >> 32; - j1 = (unsigned)j; - - if (j1) { - if (i1) - result = __umul32x32to64(i1, j1); - if ((i0 = i >> 32) != 0) - result += ((unsigned long long)(i0 * j1)) << 32; - } - if (j0 && i1) - result += ((unsigned long long)(i1 * j0)) << 32; - return (sign ? -result : result); -} - - -unsigned long long -__umul64(unsigned long long i, unsigned long long j) -{ - unsigned i0, i1, j0, j1; - unsigned long long result = 0; - - i1 = i; - j0 = j >> 32; - j1 = j; - - if (j1) { - if (i1) - result = __umul32x32to64(i1, j1); - if ((i0 = i >> 32) != 0) - result += ((unsigned long long)(i0 * j1)) << 32; - } - if (j0 && i1) - result += ((unsigned long long)(i1 * j0)) << 32; - return (result); -} diff --git a/usr/src/lib/libc/sparc/crt/muldiv64.il b/usr/src/lib/libc/sparc/crt/muldiv64.il deleted file mode 100644 index 65460eeda4..0000000000 --- a/usr/src/lib/libc/sparc/crt/muldiv64.il +++ /dev/null @@ -1,43 +0,0 @@ -! -! Copyright 2005 Sun Microsystems, Inc. All rights reserved. -! Use is subject to license terms. -! -! CDDL HEADER START -! -! The contents of this file are subject to the terms of the -! Common Development and Distribution License, Version 1.0 only -! (the "License"). You may not use this file except in compliance -! with the License. -! -! You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -! or http://www.opensolaris.org/os/licensing. -! See the License for the specific language governing permissions -! and limitations under the License. -! -! When distributing Covered Code, include this CDDL HEADER in each -! file and include the License file at usr/src/OPENSOLARIS.LICENSE. -! If applicable, add the following below this CDDL HEADER, with the -! fields enclosed by brackets "[]" replaced with your own identifying -! information: Portions Copyright [yyyy] [name of copyright owner] -! -! CDDL HEADER END -! -! ident "%Z%%M% %I% %E% SMI" - -! Reorder args from .umul to put them into 'long long' ordering - - .inline __umul32x32to64,8 - call .umul,2 - nop - mov %o0, %o2 - mov %o1, %o0 - mov %o2, %o1 - .end - -! Generates divide-by-zero trap from C - - .inline __raise_divide_by_zero,8 - ta 2 - clr %o0 - clr %o1 - .end |