summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc/sparc
diff options
context:
space:
mode:
authorjwadams <none@none>2005-09-15 17:17:44 -0700
committerjwadams <none@none>2005-09-15 17:17:44 -0700
commit4eb5116a772d340fe75c795059e1566c07b9994c (patch)
tree5975f4570cb6c8d589b5243b93f35364bb248eff /usr/src/lib/libc/sparc
parent562eee46592ccd6ead143e8a4ad19d9a5d8f9c3a (diff)
downloadillumos-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/Makefile11
-rw-r--r--usr/src/lib/libc/sparc/crt/divrem64.c404
-rw-r--r--usr/src/lib/libc/sparc/crt/hwmuldiv.s79
-rw-r--r--usr/src/lib/libc/sparc/crt/mul64.c89
-rw-r--r--usr/src/lib/libc/sparc/crt/muldiv64.il43
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