xref: /plan9-contrib/sys/src/9/vt4/fpimem.c (revision d6dfd9ef91cf0fa8514a249d5f2a550978c19369)
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