Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/mips/mips Add fp emulation for sqrt_s and sqrt_d in...
details: https://anonhg.NetBSD.org/src/rev/45308be2da7c
branches: trunk
changeset: 486149:45308be2da7c
user: castor <castor%NetBSD.org@localhost>
date: Sun May 14 06:19:32 2000 +0000
description:
Add fp emulation for sqrt_s and sqrt_d instructions
from Jeff Smith <jeffs%geocast.com@localhost>. These are needed to support
-mips2 compilation. With this change, on a QED 5231 we now pass the
paranoia tests, and are successfully using userlands built with -mips2.
diffstat:
sys/arch/mips/mips/fp.S | 182 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 181 insertions(+), 1 deletions(-)
diffs (212 lines):
diff -r 78ae42dee201 -r 45308be2da7c sys/arch/mips/mips/fp.S
--- a/sys/arch/mips/mips/fp.S Sun May 14 04:36:09 2000 +0000
+++ b/sys/arch/mips/mips/fp.S Sun May 14 06:19:32 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fp.S,v 1.17 2000/04/11 16:28:05 castor Exp $ */
+/* $NetBSD: fp.S,v 1.18 2000/05/14 06:19:32 castor Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -207,7 +207,11 @@
.word sub_s # func 1
.word mul_s # func 2
.word div_s # func 3
+#ifdef MIPS3
+ .word sqrt_s # func 4
+#else
.word ill # func 4
+#endif
.word abs_s # func 5
.word mov_s # func 6
.word neg_s # func 7
@@ -280,7 +284,11 @@
.word sub_d # func 1
.word mul_d # func 2
.word div_d # func 3
+#ifdef MIPS3
+ .word sqrt_d # func 4
+#else
.word ill # func 4
+#endif
.word abs_d # func 5
.word mov_d # func 6
.word neg_d # func 7
@@ -1263,6 +1271,178 @@
or t8, t8, v0 # from the lower remainder
b norm_d
+#ifdef MIPS3
+sqrt_s:
+ jal _C_LABEL(get_fs_s)
+
+ /* Take care of zero, negative, inf, and NaN special cases */
+ or v0, t1, t2 # sqrt(+-0) == +-0
+ beq v0, zero, result_fs_s # ...
+ bne t0, zero, 1f # sqrt(-val) == sNaN
+ bne t1, SEXP_INF, 2f # skip forward if not infinity
+ b result_fs_s # sqrt(NaN,+inf) == itself
+1: move t0, zero # result is a quiet NAN
+ li t1, SEXP_INF # sqrt(-inf,-val) == sNaN
+ li t2, SQUIET_NAN
+ b result_fs_s
+2:
+ /* normalize FS if needed */
+ bne t1, zero, 2f
+ jal _C_LABEL(renorm_fs_s)
+2: and t2, t2, (SIMPL_ONE-1) # ix &= 0x007fffff;
+ or t2, t2, SIMPL_ONE # ix |= 0x00800000;
+ and v0, t1, 1 # if (m & 1)
+ beq v0, zero, 1f # ...
+ add t2, t2, t2 # ix += ix;
+1: sra t1, t1, 1 # m = m / 2;
+
+ /* generate sqrt(FS) bit by bit */
+ add t2, t2, t2 # ix += ix;
+ move t4, zero # q = 0; (result)
+ li t8, SIMPL_ONE<<1 # r = 0x01000000;
+ move t6, zero # s = 0;
+1: beq t8, zero, 3f # while (r != 0) {
+ add t9, t6, t8 # t = s + r;
+ bgt t9, t2, 2f # if (t <= ix)
+ add t6, t9, t8 # s = t + r;
+ sub t2, t2, t9 # ix -= t;
+ add t4, t4, t8 # q += r;
+2: add t2, t2, t2 # ix += ix;
+ srl t8, t8, 1 # r >>= 1;
+ b 1b # }
+3:
+ /* rounding -- all mips rounding modes use the same rounding here */
+ beq t2, zero, 1f # if (ix != 0)
+ and v0, t4, 1 # q += q&1;
+ add t4, t4, v0 # ...
+
+ /* calculate result */
+1: srl t2, t4, 1 # ix = (q >> 1);
+ add t1, t1, SEXP_BIAS # m += 127; (re-bias)
+ li v1, SIMPL_ONE
+ and v0, t2, v1 # keep extra exponent bit
+ bne v0, zero, 1f # if it is there.
+ sub t1, t1, 1 # ...
+1:
+ nor v1, v1, v1 # ~SIMP_ONE
+ and t2, t2, v1 # ix &= ~SIMPL_ONE
+ b result_fs_s # store result (already normal)
+
+sqrt_d:
+ jal _C_LABEL(get_fs_d)
+
+ /* Take care of zero, negative, inf, and NaN special cases */
+ or v0, t1, t2 # sqrt(+-0) == +- 0
+ or v0, v0, t3 # ...
+ beq v0, zero, result_fs_d # ...
+ bne t0, zero, 1f # sqrt(-val) == sNaN
+ bne t1, DEXP_INF, 2f # skip forward if not infinity
+ b result_fs_d # sqrt(NaN,+inf) == itself
+1: move t0, zero # sqrt(-inf,-val) == sNaN
+ li t1, DEXP_INF
+ li t2, DQUIET_NAN0
+ li t3, DQUIET_NAN1
+ b result_fs_d
+2:
+ /* normalize FS if needed */
+ bne t1, zero, 2f
+ jal _C_LABEL(renorm_fs_d)
+2: and t2, t2, (DIMPL_ONE-1) # ix0 &= 0x000fffff
+ or t2, t2, DIMPL_ONE # ix0 |= 0x00100000
+ and v0, t1, 1 # if (m & 1)
+ beq v0, zero, 1f # ...
+ add t2, t2, t2 # ix0 += ix0
+ srl v0, t3, 31 # ix0 += (ix1&sign)>>31)
+ and v0, v0, 1 # ...
+ add t2, t2, v0 # ...
+ addu t3, t3, t3 # ix1 += ix1;
+1: sra t1, t1, 1 # m = m / 2;
+
+ /* generate sqrt(FS) bit by bit -- first upper */
+ addu t2, t2, t2 # ix0 += ix0;
+ srl v0, t3, 31 # ix0 += (ix1&sign)>>31)
+ and v0, v0, 1 # ...
+ add t2, t2, v0 # ...
+ addu t3, t3, t3 # ix1 += ix1;
+
+ move t4, zero # q = 0; (result)
+ move t5, zero # q1 = 0; (result)
+ move t6, zero # s0 = 0;
+ move t7, zero # s1 = 0;
+ li t8, DIMPL_ONE<<1 # t = 0x00200000;
+1: beq t8, zero, 3f # while (r != 0) {
+ add t9, t6, t8 # t = s0+r;
+ bgt t9, t2, 2f # if (t <= ix0)
+ add t6, t9, t8 # s0 = t + r;
+ sub t2, t2, t9 # ix0 -= t;
+ add t4, t4, t8 # q += r;
+2: add t2, t2, t2 # ix0 += ix0;
+ srl v0, t3, 31 # ix0 += (ix1&sign)>>31)
+ and v0, v0, 1 # ...
+ add t2, t2, v0 # ...
+ addu t3, t3, t3 # ix1 += ix1;
+ srl t8, t8, 1 # r >>= 1;
+ b 1b # }
+3:
+ /* then lower bits */
+ li t8, 1<<31 # r = sign;
+1: beq t8, zero, 4f # while (r != 0) {
+ addu v1, t7, t8 # t1 = s1 + r;
+ move t9, t6 # t = s0;
+ blt t9, t2, 2f # if ( (t<ix0) ||
+ bne t9, t2, 3f # ((t == ix0) &&
+ bgtu v1, t3, 3f # (t1 <= ix1)))
+2: addu t7, v1, t8 # s1 = t1 + r;
+ srl v0, v1, 31 # if (((t1&sign)==sign) &&
+ and v0, v0, 1 # ...
+ beq v0, zero, 2f # ...
+ srl v0, t7, 31 # (s1&sign) == 0)
+ and v0, v0, 1 # ...
+ bne v0, zero, 2f # ...
+ add t6, t6, 1 # s0 += 1;
+2: sub t2, t2, t9 # ix0 -= t;
+ bgeu t3, v1, 2f # if (ix1 < t1)
+ sub t2, t2, 1 # ix0 -= 1;
+2: subu t3, t3, v1 # ix1 -= t1;
+ addu t5, t5, t8 # q1 += r;
+3: add t2, t2, t2 # ix0 += ix0;
+ srl v0, t3, 31 # ix0 += (ix1&sign)>>31)
+ and v0, v0, 1 # ...
+ add t2, t2, v0 # ...
+ addu t3, t3, t3 # ix1 += ix1;
+ srl t8, t8, 1 # r >>= 1;
+ b 1b # }
+4:
+
+ /* rounding -- all mips rounding modes use the same rounding here */
+ or v0, t2, t3 # if (ix0 | ix1)
+ beq v0, zero, 2f # ...
+ li v0, 0xffffffff # if (q1 == 0xffffffff)
+ and v1, t2, v0 # ...
+ bne v1, v0, 1f # ...
+ move t5, zero # q1 = 0;
+ add t4, t4, 1 # q += 1;
+ b 2f # else
+1: and v0, t5, 1 # q1 += q1 & 1;
+ addu t5, t5, v0 # ...
+
+ /* calculate result */
+2: srl t2, t4, 1 # ix0 = q >> 1;
+ srl t3, t5, 1 # ix1 = q1 >> 1;
+ and v0, t4, 1 # if ((q & 1) == 1)
+ beq v0, zero, 1f # ...
+ or t3, (1<<31) # ix1 |= sign;
+1: add t1, t1, DEXP_BIAS # m += 1023;
+ li v1, DIMPL_ONE
+ and v0, t2, v1 # keep extra exponent bit
+ bne v0, zero, 1f # if it is there.
+ sub t1, t1, 1 # ...
+1:
+ nor v1, v1, v1 # ~DIMPL_ONE
+ and t2, t2, v1 # ix0 &= ~DIMPL_ONE
+ b result_fs_d # store result (already normal)
+#endif /* MIPS3 */
+
/*
* Single precision absolute value.
*/
Home |
Main Index |
Thread Index |
Old Index