5 #include <linux/kernel.h>
6 #include <linux/errno.h>
7 #include <linux/sched.h>
8 #include <asm/ptrace.h>
9 #include <asm/processor.h>
10 #include <asm/uaccess.h>
21 static unsigned int exp2s[8] = {
36 static unsigned int eexp2(
unsigned int s)
39 unsigned int mant,
frac;
42 exp = ((s >> 23) & 0xff) - 127;
45 if (exp == 128 && (s & 0x7fffff) != 0)
48 return (s & 0x80000000)? 0: 0x7f800000;
54 pwr = (s & 0x7fffff) | 0x800000;
63 exp = (pwr >> 23) + 126;
70 mant = exp2s[(pwr >> 20) & 7];
73 asm(
"mulhwu %0,%1,%2" :
"=r" (
frac)
74 :
"r" (pwr << 12),
"r" (0x172b83ff));
75 asm(
"mulhwu %0,%1,%2" :
"=r" (
frac) :
"r" (frac),
"r" (mant));
79 return mant + (exp << 23);
83 mant += 1 << (exp - 1);
91 static unsigned int elog2(
unsigned int s)
97 if (exp == 0x7f800000) {
102 if ((exp | mant) == 0)
107 asm(
"cntlzw %0,%1" :
"=r" (lz) :
"r" (mant));
109 exp = (-118 - lz) << 23;
115 if (mant >= 0xb504f3) {
117 asm(
"mulhwu %0,%1,%2" :
"=r" (mant)
118 :
"r" (mant),
"r" (0xb504f334));
120 if (mant >= 0x9837f0) {
122 asm(
"mulhwu %0,%1,%2" :
"=r" (mant)
123 :
"r" (mant),
"r" (0xd744fccb));
125 if (mant >= 0x8b95c2) {
127 asm(
"mulhwu %0,%1,%2" :
"=r" (mant)
128 :
"r" (mant),
"r" (0xeac0c6e8));
130 if (mant > 0x800000) {
133 asm(
"mulhwu %0,%1,%2" :
"=r" (
frac)
134 :
"r" ((mant - 0x800000) << 1),
"r" (0xb0c7cd3a));
137 s = exp & 0x80000000;
141 asm(
"cntlzw %0,%1" :
"=r" (lz) :
"r" (exp));
147 s += ((lz + 126) << 23) +
exp;
154 static int ctsxs(
unsigned int x,
int scale,
unsigned int *vscrp)
158 exp = (x >> 23) & 0xff;
160 if (exp == 255 && mant != 0)
162 exp = exp - 127 + scale;
167 if (x + (scale << 23) != 0xcf000000)
169 return (x & 0x80000000)? 0x80000000: 0x7fffffff;
172 mant = (mant << 7) >> (30 -
exp);
173 return (x & 0x80000000)? -mant: mant;
176 static unsigned int ctuxs(
unsigned int x,
int scale,
unsigned int *vscrp)
181 exp = (x >> 23) & 0xff;
183 if (exp == 255 && mant != 0)
185 exp = exp - 127 + scale;
188 if (x & 0x80000000) {
199 mant = (mant << 8) >> (31 -
exp);
204 static unsigned int rfiz(
unsigned int x)
208 exp = ((x >> 23) & 0xff) - 127;
209 if (exp == 128 && (x & 0x7fffff) != 0)
214 return x & 0x80000000;
215 return x & ~(0x7fffff >>
exp);
219 static unsigned int rfii(
unsigned int x)
223 exp = ((x >> 23) & 0xff) - 127;
224 if (exp == 128 && (x & 0x7fffff) != 0)
228 if ((x & 0x7fffffff) == 0)
232 return (x & 0x80000000) | 0x3f800000;
233 mask = 0x7fffff >>
exp;
236 return (x + mask) & ~mask;
240 static unsigned int rfin(
unsigned int x)
244 exp = ((x >> 23) & 0xff) - 127;
245 if (exp == 128 && (x & 0x7fffff) != 0)
250 return x & 0x80000000;
253 return (x & 0x80000000) | 0x3f800000;
254 half = 0x400000 >>
exp;
256 return (x + half) & ~(0x7fffff >>
exp);
262 unsigned int va, vb,
vc, vd;
267 if ((instr >> 26) != 4)
269 vd = (instr >> 21) & 0x1f;
270 va = (instr >> 16) & 0x1f;
271 vb = (instr >> 11) & 0x1f;
272 vc = (instr >> 6) & 0x1f;
275 switch (instr & 0x3f) {
279 vaddfp(&vrs[vd], &vrs[va], &vrs[vb]);
282 vsubfp(&vrs[vd], &vrs[va], &vrs[vb]);
285 vrefp(&vrs[vd], &vrs[vb]);
291 for (i = 0; i < 4; ++
i)
292 vrs[vd].
u[i] = eexp2(vrs[vb].
u[i]);
295 for (i = 0; i < 4; ++
i)
296 vrs[vd].
u[i] = elog2(vrs[vb].
u[i]);
299 for (i = 0; i < 4; ++
i)
300 vrs[vd].
u[i] = rfin(vrs[vb].
u[i]);
303 for (i = 0; i < 4; ++
i)
304 vrs[vd].
u[i] = rfiz(vrs[vb].
u[i]);
307 for (i = 0; i < 4; ++
i) {
308 u32 x = vrs[vb].u[
i];
309 x = (x & 0x80000000)? rfiz(x): rfii(x);
314 for (i = 0; i < 4; ++
i) {
315 u32 x = vrs[vb].u[
i];
316 x = (x & 0x80000000)? rfii(x): rfiz(x);
321 for (i = 0; i < 4; ++
i)
322 vrs[vd].
u[i] = ctuxs(vrs[vb].
u[i], va,
326 for (i = 0; i < 4; ++
i)
327 vrs[vd].
u[i] = ctsxs(vrs[vb].
u[i], va,
335 vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
338 vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);