update fpi to support vlongs. Reference: /n/atom/patch/applied2013/fpivlong Date: Wed Jul 31 20:52:10 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/9/port/fpi.c Wed Jul 31 20:50:42 2013 +++ /sys/src/9/port/fpi.c Wed Jul 31 20:50:43 2013 @@ -1,6 +1,9 @@ /* * Floating Point Interpreter. * shamelessly stolen from an original by ark. + * + * NB: the Internal arguments to fpisub and fpidiv are reversed from + * what you might naively expect: they compute y-x and y/x, respectively. */ #include "../port/fpi.h" --- /sys/src/9/port/fpi.h Wed Jul 31 20:50:44 2013 +++ /sys/src/9/port/fpi.h Wed Jul 31 20:50:44 2013 @@ -1,4 +1,5 @@ typedef long Word; +typedef long long Vlong; typedef unsigned long Single; typedef struct { unsigned long l; @@ -56,6 +57,8 @@ extern void fpis2i(Internal *, void *); extern void fpid2i(Internal *, void *); extern void fpiw2i(Internal *, void *); +extern void fpiv2i(Internal *, void *); extern void fpii2s(void *, Internal *); extern void fpii2d(void *, Internal *); extern void fpii2w(Word *, Internal *); +extern void fpii2v(Vlong *, Internal *); --- /sys/src/9/port/fpimem.c Wed Jul 31 20:50:45 2013 +++ /sys/src/9/port/fpimem.c Wed Jul 31 20:50:45 2013 @@ -71,6 +71,44 @@ } void +fpiv2i(Internal *i, void *v) +{ + Vlong w, word = *(Vlong*)v; + short e; + + if(word < 0){ + i->s = 1; + word = -word; + } + else + i->s = 0; + if(word == 0){ + SetZero(i); + return; + } + if(word > 0){ + for (e = 0, w = word; w; w >>= 1, e++) + ; + } else + e = 64; + if(e > FractBits){ + i->h = word>>(e - FractBits); + i->l = (word & ((1<<(e - FractBits)) - 1))<<(2*FractBits - e); + } + else { + i->h = word<<(FractBits - e); + i->l = 0; + } + i->e = (e - 1) + ExpBias; +} + +/* + * Note that all of these conversions from Internal format + * potentially alter *i, so it should be a disposable copy + * of the value to be converted. + */ + +void fpii2s(void *v, Internal *i) { short e; @@ -128,6 +166,27 @@ w = 0x7FFFFFFF; else if(e > FractBits) w = (i->h<<(e - FractBits))|(i->l>>(2*FractBits - e)); + else + w = i->h>>(FractBits-e); + if(i->s) + w = -w; + *word = w; +} + +void +fpii2v(Vlong *word, Internal *i) +{ + Vlong w; + short e; + + fpiround(i); + e = (i->e - ExpBias) + 1; + if(e <= 0) + w = 0; + else if(e > 63) + w = (1ull<<63) - 1; /* maxlong */ + else if(e > FractBits) + w = (Vlong)i->h<<(e - FractBits) | i->l>>(2*FractBits - e); else w = i->h>>(FractBits-e); if(i->s)