xref: /plan9/sys/src/9/port/fpimem.c (revision 426f2a32150b219ea919a1d76cbd0c50d6d55686)
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