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
fpis2i(Internal * i,void * v)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
fpid2i(Internal * i,void * v)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
fpiw2i(Internal * i,void * v)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
fpiv2i(Internal * i,void * v)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
fpii2s(void * v,Internal * i)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
fpii2d(void * v,Internal * i)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
fpii2w(Word * word,Internal * i)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
fpii2v(Vlong * word,Internal * i)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