1 #include "fpi.h" 2 3 /* 4 * the following routines depend on memory format, not the machine 5 */ 6 7 enum { 8 Sign = 1u << 31, 9 }; 10 11 void 12 fpis2i(Internal *i, void *v) 13 { 14 Single *s = v; 15 16 i->s = (*s & Sign) ? 1: 0; 17 if((*s & ~Sign) == 0){ 18 SetZero(i); 19 return; 20 } 21 i->e = ((*s>>23) & 0x00FF) - SingleExpBias + ExpBias; 22 i->h = (*s & 0x007FFFFF)<<(1+NGuardBits); 23 i->l = 0; 24 if(i->e) 25 i->h |= HiddenBit; 26 else 27 i->e++; 28 } 29 30 void 31 fpid2i(Internal *i, void *v) 32 { 33 Double *d = v; 34 35 i->s = (d->h & Sign) ? 1: 0; 36 i->e = (d->h>>20) & 0x07FF; 37 i->h = ((d->h & 0x000FFFFF)<<(4+NGuardBits))|((d->l>>25) & 0x7F); 38 i->l = (d->l & 0x01FFFFFF)<<NGuardBits; 39 if(i->e) 40 i->h |= HiddenBit; 41 else 42 i->e++; 43 } 44 45 void 46 fpiw2i(Internal *i, void *v) 47 { 48 Word w, word = *(Word*)v; 49 short e; 50 51 if(word < 0){ 52 i->s = 1; 53 word = -word; 54 } 55 else 56 i->s = 0; 57 if(word == 0){ 58 SetZero(i); 59 return; 60 } 61 if(word > 0){ 62 for (e = 0, w = word; w; w >>= 1, e++) 63 ; 64 } else 65 e = 32; 66 if(e > FractBits){ 67 i->h = word>>(e - FractBits); 68 i->l = (word & ((1<<(e - FractBits)) - 1))<<(2*FractBits - e); 69 } 70 else { 71 i->h = word<<(FractBits - e); 72 i->l = 0; 73 } 74 i->e = (e - 1) + ExpBias; 75 } 76 77 void 78 fpiv2i(Internal *i, void *v) 79 { 80 Vlong w, word = *(Vlong*)v; 81 short e; 82 83 if(word < 0){ 84 i->s = 1; 85 word = -word; 86 } 87 else 88 i->s = 0; 89 if(word == 0){ 90 SetZero(i); 91 return; 92 } 93 if(word > 0){ 94 for (e = 0, w = word; w; w >>= 1, e++) 95 ; 96 } else 97 e = 64; 98 if(e > FractBits){ 99 i->h = word>>(e - FractBits); 100 i->l = (word & ((1<<(e - FractBits)) - 1))<<(2*FractBits - e); 101 } 102 else { 103 i->h = word<<(FractBits - e); 104 i->l = 0; 105 } 106 i->e = (e - 1) + ExpBias; 107 } 108 109 /* 110 * Note that all of these conversions from Internal format 111 * potentially alter *i, so it should be a disposable copy 112 * of the value to be converted. 113 */ 114 115 void 116 fpii2s(void *v, Internal *i) 117 { 118 short e; 119 Single *s = (Single*)v; 120 121 fpiround(i); 122 if(i->h & HiddenBit) 123 i->h &= ~HiddenBit; 124 else 125 i->e--; 126 *s = i->s ? Sign: 0; 127 e = i->e; 128 if(e < ExpBias){ 129 if(e <= (ExpBias - SingleExpBias)) 130 return; 131 e = SingleExpBias - (ExpBias - e); 132 } 133 else if(e >= (ExpBias + (SingleExpMax-SingleExpBias))){ 134 *s |= SingleExpMax<<23; 135 return; 136 } 137 else 138 e = SingleExpBias + (e - ExpBias); 139 *s |= (e<<23)|(i->h>>(1+NGuardBits)); 140 } 141 142 void 143 fpii2d(void *v, Internal *i) 144 { 145 Double *d = (Double*)v; 146 147 fpiround(i); 148 if(i->h & HiddenBit) 149 i->h &= ~HiddenBit; 150 else 151 i->e--; 152 i->l = ((i->h & GuardMask)<<25)|(i->l>>NGuardBits); 153 i->h >>= NGuardBits; 154 d->h = i->s ? Sign: 0; 155 d->h |= (i->e<<20)|((i->h & 0x00FFFFFF)>>4); 156 d->l = (i->h<<28)|i->l; 157 } 158 159 void 160 fpii2w(Word *word, Internal *i) 161 { 162 Word w; 163 short e; 164 165 fpiround(i); 166 e = (i->e - ExpBias) + 1; 167 if(e <= 0) 168 w = 0; 169 else if(e > 31) 170 w = 0x7FFFFFFF; 171 else if(e > FractBits) 172 w = (i->h<<(e - FractBits))|(i->l>>(2*FractBits - e)); 173 else 174 w = i->h>>(FractBits-e); 175 if(i->s) 176 w = -w; 177 *word = w; 178 } 179 180 void 181 fpii2v(Vlong *word, Internal *i) 182 { 183 Vlong w; 184 short e; 185 186 fpiround(i); 187 e = (i->e - ExpBias) + 1; 188 if(e <= 0) 189 w = 0; 190 else if(e > 63) 191 w = (1ull<<63) - 1; /* maxlong */ 192 else if(e > FractBits) 193 w = (Vlong)i->h<<(e - FractBits) | i->l>>(2*FractBits - e); 194 else 195 w = i->h>>(FractBits-e); 196 if(i->s) 197 w = -w; 198 *word = w; 199 } 200