ref: d2af6b40af268fafdbd04c0222e785167b9ae021
parent: 9124e491e5d172feec53dd662c2fe6d999cb2d3f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Oct 4 15:49:02 EDT 2015
libc: add _uv2d()/uv2f() and _vas*d() functions to vlrt.c on 32 bit archs, implement 64 bit vasop with floatingpoint right hand side. also added is uvlong->double conversion function.
--- a/sys/src/ape/lib/ap/386/vlrt.c
+++ b/sys/src/ape/lib/ap/386/vlrt.c
@@ -28,19 +28,8 @@
void abort(void);
-void
-_subv(Vlong *r, Vlong a, Vlong b)
-{
- ulong lo, hi;
+void _subv(Vlong*, Vlong, Vlong);
- lo = a.lo - b.lo;
- hi = a.hi - b.hi;
- if(lo > a.lo)
- hi--;
- r->lo = lo;
- r->hi = hi;
-}
-
void
_d2v(Vlong *y, double d)
{
@@ -100,7 +89,6 @@
void
_f2v(Vlong *y, float f)
{
-
_d2v(y, f);
}
@@ -124,10 +112,109 @@
return _v2d(x);
}
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
+}
+
ulong _div64by32(Vlong, ulong, ulong*);
void _mul64by32(Vlong*, Vlong, ulong);
static void
+slowdodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
+{
+ ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
+ int i;
+
+ numhi = num.hi;
+ numlo = num.lo;
+ denhi = den.hi;
+ denlo = den.lo;
+
+ /*
+ * get a divide by zero
+ */
+ if(denlo==0 && denhi==0) {
+ numlo = numlo / denlo;
+ }
+
+ /*
+ * set up the divisor and find the number of iterations needed
+ */
+ if(numhi >= SIGN(32)) {
+ quohi = SIGN(32);
+ quolo = 0;
+ } else {
+ quohi = numhi;
+ quolo = numlo;
+ }
+ i = 0;
+ while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
+ denhi = (denhi<<1) | (denlo>>31);
+ denlo <<= 1;
+ i++;
+ }
+
+ quohi = 0;
+ quolo = 0;
+ for(; i >= 0; i--) {
+ quohi = (quohi<<1) | (quolo>>31);
+ quolo <<= 1;
+ if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
+ t = numlo;
+ numlo -= denlo;
+ if(numlo > t)
+ numhi--;
+ numhi -= denhi;
+ quolo |= 1;
+ }
+ denlo = (denlo>>1) | (denhi<<31);
+ denhi >>= 1;
+ }
+
+ if(q) {
+ q->lo = quolo;
+ q->hi = quohi;
+ }
+ if(r) {
+ r->lo = numlo;
+ r->hi = numhi;
+ }
+}
+
+static void
dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp)
{
ulong n;
@@ -149,12 +236,12 @@
q.hi = 0;
n = num.hi/den.hi;
_mul64by32(&x, den, n);
- if(x.hi > num.hi || (x.hi == num.hi && x.lo > num.lo)){
- n--;
- _mul64by32(&x, den, n);
+ if(x.hi > num.hi || (x.hi == num.hi && x.lo > num.lo))
+ slowdodiv(num, den, &q, &r);
+ else {
+ q.lo = n;
+ _subv(&r, num, x);
}
- q.lo = n;
- _subv(&r, num, x);
} else {
if(num.hi >= den.lo){
q.hi = n = num.hi/den.lo;
--- a/sys/src/ape/lib/ap/arm/vlrt.c
+++ b/sys/src/ape/lib/ap/arm/vlrt.c
@@ -128,7 +128,46 @@
return _v2d(x);
}
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
+}
+
+/* too many of these are also needed by profiler; leave them out */
+#pragma profile off
+
static void
dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
{
@@ -502,6 +541,7 @@
ret->lo = t;
ret->hi = t >> 31;
}
+
void
_ul2v(Vlong *ret, ulong ul)
--- a/sys/src/ape/lib/ap/mips/vlrt.c
+++ b/sys/src/ape/lib/ap/mips/vlrt.c
@@ -28,6 +28,8 @@
void abort(void);
+/* needed by profiler; can't be profiled. */
+#pragma profile off
void
_addv(Vlong *r, Vlong a, Vlong b)
{
@@ -54,6 +56,8 @@
r->hi = hi;
}
+#pragma profile on
+
void
_d2v(Vlong *y, double d)
{
@@ -113,7 +117,6 @@
void
_f2v(Vlong *y, float f)
{
-
_d2v(y, f);
}
@@ -135,6 +138,43 @@
_v2f(Vlong x)
{
return _v2d(x);
+}
+
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
}
static void
--- a/sys/src/ape/lib/ap/power/vlrt.c
+++ b/sys/src/ape/lib/ap/power/vlrt.c
@@ -99,6 +99,43 @@
return _v2d(x);
}
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
+}
+
void
_divvu(Vlong *q, Vlong n, Vlong d)
{
--- a/sys/src/ape/lib/ap/sparc/vlrt.c
+++ b/sys/src/ape/lib/ap/sparc/vlrt.c
@@ -28,6 +28,8 @@
void abort(void);
+/* needed by profiler; can't be profiled */
+#pragma profile off
void
_addv(Vlong *r, Vlong a, Vlong b)
{
@@ -54,6 +56,8 @@
r->hi = hi;
}
+#pragma profile on
+
void
_d2v(Vlong *y, double d)
{
@@ -135,6 +139,43 @@
_v2f(Vlong x)
{
return _v2d(x);
+}
+
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
}
static void
--- a/sys/src/libc/386/vlrt.c
+++ b/sys/src/libc/386/vlrt.c
@@ -89,7 +89,6 @@
void
_f2v(Vlong *y, float f)
{
-
_d2v(y, f);
}
@@ -111,6 +110,43 @@
_v2f(Vlong x)
{
return _v2d(x);
+}
+
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
}
ulong _div64by32(Vlong, ulong, ulong*);
--- a/sys/src/libc/arm/vlrt.c
+++ b/sys/src/libc/arm/vlrt.c
@@ -128,6 +128,43 @@
return _v2d(x);
}
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
+}
+
/* too many of these are also needed by profiler; leave them out */
#pragma profile off
--- a/sys/src/libc/mips/vlrt.c
+++ b/sys/src/libc/mips/vlrt.c
@@ -117,7 +117,6 @@
void
_f2v(Vlong *y, float f)
{
-
_d2v(y, f);
}
@@ -139,6 +138,43 @@
_v2f(Vlong x)
{
return _v2d(x);
+}
+
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
}
static void
--- a/sys/src/libc/power/vlrt.c
+++ b/sys/src/libc/power/vlrt.c
@@ -99,6 +99,43 @@
return _v2d(x);
}
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
+}
+
void
_divvu(Vlong *q, Vlong n, Vlong d)
{
--- a/sys/src/libc/sparc/vlrt.c
+++ b/sys/src/libc/sparc/vlrt.c
@@ -141,6 +141,43 @@
return _v2d(x);
}
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
+}
+
static void
dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
{
--- a/sys/src/libc/spim/vlrt.c
+++ b/sys/src/libc/spim/vlrt.c
@@ -117,7 +117,6 @@
void
_f2v(Vlong *y, float f)
{
-
_d2v(y, f);
}
@@ -139,6 +138,43 @@
_v2f(Vlong x)
{
return _v2d(x);
+}
+
+double
+_uv2d(Vlong x)
+{
+ return x.hi*4294967296. + x.lo;
+}
+
+float
+_uv2f(Vlong x)
+{
+ return _uv2d(x);
+}
+
+void
+_vasaddd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)+rv);
+ *ret = *lv;
+}
+void
+_vassubd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)-rv);
+ *ret = *lv;
+}
+void
+_vasmuld(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)*rv);
+ *ret = *lv;
+}
+void
+_vasdivd(Vlong *ret, Vlong *lv, double v2d(Vlong), double rv)
+{
+ _d2v(lv, v2d(*lv)/rv);
+ *ret = *lv;
}
static void