ref: e1cd22504e26d0a732a4219d38d6e5fe3e03aa21
dir: /sys/src/9/mt7688/fpimem.c/
#include "fpi.h" /* * the following routines depend on memory format, not the machine */ enum { Sign = 1u << 31, }; void fpis2i(Internal *i, void *v) { Single *s = v; i->s = (*s & Sign) ? 1: 0; if((*s & ~Sign) == 0){ SetZero(i); return; } i->e = ((*s>>23) & 0x00FF) - SingleExpBias + ExpBias; i->h = (*s & 0x007FFFFF)<<(1+NGuardBits); i->l = 0; if(i->e) i->h |= HiddenBit; else i->e++; } void fpid2i(Internal *i, void *v) { Double *d = v; i->s = (d->h & Sign) ? 1: 0; i->e = (d->h>>20) & 0x07FF; i->h = ((d->h & 0x000FFFFF)<<(4+NGuardBits))|((d->l>>25) & 0x7F); i->l = (d->l & 0x01FFFFFF)<<NGuardBits; if(i->e) i->h |= HiddenBit; else i->e++; } void fpiw2i(Internal *i, void *v) { Word w, word = *(Word*)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 = 32; 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; } 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; Single *s = (Single*)v; fpiround(i); if(i->h & HiddenBit) i->h &= ~HiddenBit; else i->e--; *s = i->s ? Sign: 0; e = i->e; if(e < ExpBias){ if(e <= (ExpBias - SingleExpBias)) return; e = SingleExpBias - (ExpBias - e); } else if(e >= (ExpBias + (SingleExpMax-SingleExpBias))){ *s |= SingleExpMax<<23; return; } else e = SingleExpBias + (e - ExpBias); *s |= (e<<23)|(i->h>>(1+NGuardBits)); } void fpii2d(void *v, Internal *i) { Double *d = (Double*)v; fpiround(i); if(i->h & HiddenBit) i->h &= ~HiddenBit; else i->e--; i->l = ((i->h & GuardMask)<<25)|(i->l>>NGuardBits); i->h >>= NGuardBits; d->h = i->s ? Sign: 0; d->h |= (i->e<<20)|((i->h & 0x00FFFFFF)>>4); d->l = (i->h<<28)|i->l; } void fpii2w(Word *word, Internal *i) { Word w; short e; fpiround(i); e = (i->e - ExpBias) + 1; if(e <= 0) w = 0; else if(e > 31) 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) w = -w; *word = w; }