xref: /inferno-os/os/port/fpimem.c (revision d0e1d143ef6f03c75c008c7ec648859dd260cbab)
1 #include "fpi.h"
2 
3 /*
4  * the following routines depend on memory format, not the machine
5  */
6 
7 void
8 fpis2i(Internal *i, void *v)
9 {
10 	Single *s = v;
11 
12 	i->s = (*s & 0x80000000) ? 1: 0;
13 	if((*s & ~0x80000000) == 0){
14 		SetZero(i);
15 		return;
16 	}
17 	i->e = ((*s>>23) & 0x00FF) - SingleExpBias + ExpBias;
18 	i->h = (*s & 0x007FFFFF)<<(1+NGuardBits);
19 	i->l = 0;
20 	if(i->e)
21 		i->h |= HiddenBit;
22 	else
23 		i->e++;
24 }
25 
26 void
27 fpid2i(Internal *i, void *v)
28 {
29 	Double *d = v;
30 
31 	i->s = (d->h & 0x80000000) ? 1: 0;
32 	i->e = (d->h>>20) & 0x07FF;
33 	i->h = ((d->h & 0x000FFFFF)<<(4+NGuardBits))|((d->l>>25) & 0x7F);
34 	i->l = (d->l & 0x01FFFFFF)<<NGuardBits;
35 	if(i->e)
36 		i->h |= HiddenBit;
37 	else
38 		i->e++;
39 }
40 
41 void
42 fpiw2i(Internal *i, void *v)
43 {
44 	Word w, word = *(Word*)v;
45 	int e;
46 
47 	if(word < 0){
48 		i->s = 1;
49 		word = -word;
50 	}
51 	else
52 		i->s = 0;
53 	if(word == 0){
54 		SetZero(i);
55 		return;
56 	}
57 	if(word > 0){
58 		for (e = 0, w = word; w; w >>= 1, e++)
59 			;
60 	} else
61 		e = 32;
62 	if(e > FractBits){
63 		i->h = word>>(e - FractBits);
64 		i->l = (word & ((1<<(e - FractBits)) - 1))<<(2*FractBits - e);
65 	}
66 	else {
67 		i->h = word<<(FractBits - e);
68 		i->l = 0;
69 	}
70 	i->e = (e - 1) + ExpBias;
71 }
72 
73 void
74 fpii2s(void *v, Internal *i)
75 {
76 	int e;
77 	Single *s = (Single*)v;
78 
79 	fpiround(i);
80 	if(i->h & HiddenBit)
81 		i->h &= ~HiddenBit;
82 	else
83 		i->e--;
84 	*s = i->s ? 0x80000000: 0;
85 	e = i->e;
86 	if(e < ExpBias){
87 		if(e <= (ExpBias - SingleExpBias))
88 			return;
89 		e = SingleExpBias - (ExpBias - e);
90 	}
91 	else  if(e >= (ExpBias + (SingleExpMax-SingleExpBias))){
92 		*s |= SingleExpMax<<23;
93 		return;
94 	}
95 	else
96 		e = SingleExpBias + (e - ExpBias);
97 	*s |= (e<<23)|(i->h>>(1+NGuardBits));
98 }
99 
100 void
101 fpii2d(void *v, Internal *i)
102 {
103 	Double *d = (Double*)v;
104 
105 	fpiround(i);
106 	if(i->h & HiddenBit)
107 		i->h &= ~HiddenBit;
108 	else
109 		i->e--;
110 	i->l = ((i->h & GuardMask)<<25)|(i->l>>NGuardBits);
111 	i->h >>= NGuardBits;
112 	d->h = i->s ? 0x80000000: 0;
113 	d->h |= (i->e<<20)|((i->h & 0x00FFFFFF)>>4);
114 	d->l = (i->h<<28)|i->l;
115 }
116 
117 void
118 fpii2w(Word *word, Internal *i)
119 {
120 	Word w;
121 	int e;
122 
123 	fpiround(i);
124 	e = (i->e - ExpBias) + 1;
125 	if(e <= 0)
126 		w = 0;
127 	else if(e > 31)
128 		w = 0x7FFFFFFF;
129 	else if(e > FractBits)
130 		w = (i->h<<(e - FractBits))|(i->l>>(2*FractBits - e));
131 	else
132 		w = i->h>>(FractBits-e);
133 	if(i->s)
134 		w = -w;
135 	*word = w;
136 }
137