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