1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fpi.h"
6
7 /*
8 * the following routines depend on memory format, not the machine
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 & 0x80000000) ? 1: 0;
17 if((*s & ~0x80000000) == 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 & 0x80000000) ? 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 int 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
fpii2s(void * v,Internal * i)78 fpii2s(void *v, Internal *i)
79 {
80 int e;
81 Single *s = (Single*)v;
82
83 fpiround(i);
84 if(i->h & HiddenBit)
85 i->h &= ~HiddenBit;
86 else
87 i->e--;
88 *s = i->s ? 0x80000000: 0;
89 e = i->e;
90 if(e < ExpBias){
91 if(e <= (ExpBias - SingleExpBias))
92 return;
93 e = SingleExpBias - (ExpBias - e);
94 }
95 else if(e >= (ExpBias + (SingleExpMax-SingleExpBias))){
96 *s |= SingleExpMax<<23;
97 return;
98 }
99 else
100 e = SingleExpBias + (e - ExpBias);
101 *s |= (e<<23)|(i->h>>(1+NGuardBits));
102 }
103
104 void
fpii2d(void * v,Internal * i)105 fpii2d(void *v, Internal *i)
106 {
107 Double *d = (Double*)v;
108
109 fpiround(i);
110 if(i->h & HiddenBit)
111 i->h &= ~HiddenBit;
112 else
113 i->e--;
114 i->l = ((i->h & GuardMask)<<25)|(i->l>>NGuardBits);
115 i->h >>= NGuardBits;
116 d->h = i->s ? 0x80000000: 0;
117 d->h |= (i->e<<20)|((i->h & 0x00FFFFFF)>>4);
118 d->l = (i->h<<28)|i->l;
119 }
120
121 void
fpii2w(Word * word,Internal * i)122 fpii2w(Word *word, Internal *i)
123 {
124 Word w;
125 int e;
126
127 fpiround(i);
128 e = (i->e - ExpBias) + 1;
129 if(e <= 0)
130 w = 0;
131 else if(e > 31)
132 w = 0x7FFFFFFF;
133 else if(e > FractBits)
134 w = (i->h<<(e - FractBits))|(i->l>>(2*FractBits - e));
135 else
136 w = i->h>>(FractBits-e);
137 if(i->s)
138 w = -w;
139 *word = w;
140 }
141