33 #include <linux/kernel.h>
34 #include <linux/bitops.h>
36 #include <asm/div64.h>
42 static struct vfp_single vfp_single_default_qnan = {
50 pr_debug(
"VFP: %s: sign=%d exponent=%d significand=%08x\n",
54 static void vfp_single_normalise_denormal(
struct vfp_single *vs)
58 vfp_single_dump(
"normalise_denormal: in", vs);
65 vfp_single_dump(
"normalise_denormal: out", vs);
69 #define vfp_single_normaliseround(sd,vsd,fpscr,except,func) __vfp_single_normaliseround(sd,vsd,fpscr,except)
78 vfp_single_dump(
"pack: in", vs);
102 shift = 32 - fls(significand);
103 if (shift < 32 && shift) {
105 significand <<= shift;
111 vfp_single_dump(
"pack: normalised", vs);
117 underflow = exponent < 0;
119 significand = vfp_shiftright32jamming(significand, -exponent);
124 vfp_single_dump(
"pack: tiny number", vs);
145 pr_debug(
"VFP: rounding increment = 0x%08x\n", incr);
150 if ((significand + incr) < significand) {
152 significand = (significand >> 1) | (significand & 1);
157 vfp_single_dump(
"pack: overflow", vs);
176 if (exponent >= 254) {
188 if (exponent || significand > 0x80000000)
197 vfp_single_dump(
"pack: final", vs);
199 s32 d = vfp_single_pack(vs);
201 pr_debug(
"VFP: %s: d(s%d)=%08x exceptions=%08x\n", func,
221 tn = vfp_single_type(vsn);
224 tm = vfp_single_type(vsm);
230 nan = &vfp_single_default_qnan;
265 static u32 vfp_single_fcpy(
int sd,
int unused,
s32 m,
u32 fpscr)
271 static u32 vfp_single_fneg(
int sd,
int unused,
s32 m,
u32 fpscr)
277 static const u16 sqrt_oddadjust[] = {
278 0x0004, 0x0022, 0x005d, 0x00b1, 0x011d, 0x019f, 0x0236, 0x02e0,
279 0x039c, 0x0468, 0x0545, 0x0631, 0x072b, 0x0832, 0x0946, 0x0a67
282 static const u16 sqrt_evenadjust[] = {
283 0x0a2d, 0x08af, 0x075a, 0x0629, 0x051a, 0x0429, 0x0356, 0x029e,
284 0x0200, 0x0179, 0x0109, 0x00af, 0x0068, 0x0034, 0x0012, 0x0002
292 if ((significand & 0xc0000000) != 0x40000000) {
296 a = significand << 1;
297 index = (a >> 27) & 15;
299 z = 0x4000 + (a >> 17) - sqrt_oddadjust[index];
300 z = ((a / z) << 14) + (z << 15);
303 z = 0x8000 + (a >> 17) - sqrt_evenadjust[index];
305 z = (z >= 0x20000) ? 0xffff8000 : (z << 15);
316 static u32 vfp_single_fsqrt(
int sd,
int unused,
s32 m,
u32 fpscr)
321 vfp_single_unpack(&vsm, m);
322 tm = vfp_single_type(&vsm);
327 ret = vfp_propagate_nan(vsp, &vsm,
NULL, fpscr);
328 else if (vsm.
sign == 0) {
334 vsp = &vfp_single_default_qnan;
351 vfp_single_normalise_denormal(&vsm);
359 vfp_single_dump(
"sqrt", &vsm);
368 vfp_single_dump(
"sqrt estimate", &vsd);
383 pr_debug(
"VFP: term=%016llx rem=%016llx\n", term, rem);
403 static u32 vfp_compare(
int sd,
int signal_on_qnan,
s32 m,
u32 fpscr)
462 static u32 vfp_single_fcmp(
int sd,
int unused,
s32 m,
u32 fpscr)
464 return vfp_compare(sd, 0, m, fpscr);
467 static u32 vfp_single_fcmpe(
int sd,
int unused,
s32 m,
u32 fpscr)
469 return vfp_compare(sd, 1, m, fpscr);
472 static u32 vfp_single_fcmpz(
int sd,
int unused,
s32 m,
u32 fpscr)
474 return vfp_compare(sd, 0, 0, fpscr);
477 static u32 vfp_single_fcmpez(
int sd,
int unused,
s32 m,
u32 fpscr)
479 return vfp_compare(sd, 1, 0, fpscr);
482 static u32 vfp_single_fcvtd(
int dd,
int unused,
s32 m,
u32 fpscr)
489 vfp_single_unpack(&vsm, m);
491 tm = vfp_single_type(&vsm);
499 if (tm & VFP_DENORMAL)
500 vfp_single_normalise_denormal(&vsm);
513 }
else if (tm & VFP_ZERO)
516 vdd.exponent = vsm.
exponent + (1023 - 127);
525 static u32 vfp_single_fuito(
int sd,
int unused,
s32 m,
u32 fpscr)
536 static u32 vfp_single_fsito(
int sd,
int unused,
s32 m,
u32 fpscr)
540 vs.
sign = (m & 0x80000000) >> 16;
547 static u32 vfp_single_ftoui(
int sd,
int unused,
s32 m,
u32 fpscr)
550 u32 d, exceptions = 0;
554 vfp_single_unpack(&vsm, m);
555 vfp_single_dump(
"VSM", &vsm);
560 tm = vfp_single_type(&vsm);
561 if (tm & VFP_DENORMAL)
568 d = vsm.
sign ? 0 : 0xffffffff;
570 }
else if (vsm.
exponent >= 127 - 1) {
571 int shift = 127 + 31 - vsm.
exponent;
590 if ((rem + incr) < rem) {
615 pr_debug(
"VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
622 static u32 vfp_single_ftouiz(
int sd,
int unused,
s32 m,
u32 fpscr)
627 static u32 vfp_single_ftosi(
int sd,
int unused,
s32 m,
u32 fpscr)
630 u32 d, exceptions = 0;
634 vfp_single_unpack(&vsm, m);
635 vfp_single_dump(
"VSM", &vsm);
640 tm = vfp_single_type(&vsm);
641 if (vfp_single_type(&vsm) & VFP_DENORMAL)
647 }
else if (vsm.
exponent >= 127 + 32) {
655 }
else if (vsm.
exponent >= 127 - 1) {
656 int shift = 127 + 31 - vsm.
exponent;
673 if ((rem + incr) < rem && d < 0xffffffff)
675 if (d > 0x7fffffff + (vsm.
sign != 0)) {
676 d = 0x7fffffff + (vsm.
sign != 0);
694 pr_debug(
"VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
701 static u32 vfp_single_ftosiz(
int sd,
int unused,
s32 m,
u32 fpscr)
706 static struct op fops_ext[32] = {
736 tn = vfp_single_type(vsn);
737 tm = vfp_single_type(vsm);
748 vsp = &vfp_single_default_qnan;
755 }
else if (tn & VFP_INFINITY && tm &
VFP_NUMBER) {
764 return vfp_propagate_nan(vsd, vsn, vsm, fpscr);
778 pr_info(
"VFP: bad FP values in %s\n", __func__);
779 vfp_single_dump(
"VSN", vsn);
780 vfp_single_dump(
"VSM", vsm);
799 return vfp_single_fadd_nonnumber(vsd, vsn, vsm, fpscr);
812 m_sig = vfp_shiftright32jamming(vsm->
significand, exp_diff);
819 if ((
s32)m_sig < 0) {
822 }
else if (m_sig == 0) {
837 vfp_single_dump(
"VSN", vsn);
838 vfp_single_dump(
"VSM", vsm);
849 pr_debug(
"VFP: swapping M <-> N\n");
859 return vfp_propagate_nan(vsd, vsn, vsm, fpscr);
861 *vsd = vfp_single_default_qnan;
887 vfp_single_dump(
"VSD", vsd);
891 #define NEG_MULTIPLY (1 << 0)
892 #define NEG_SUBTRACT (1 << 1)
895 vfp_single_multiply_accumulate(
int sd,
int sn,
s32 m,
u32 fpscr,
u32 negate,
char *func)
902 pr_debug(
"VFP: s%u = %08x\n", sn, v);
903 vfp_single_unpack(&vsn, v);
905 vfp_single_normalise_denormal(&vsn);
907 vfp_single_unpack(&vsm, m);
909 vfp_single_normalise_denormal(&vsm);
911 exceptions = vfp_single_multiply(&vsp, &vsn, &vsm, fpscr);
916 pr_debug(
"VFP: s%u = %08x\n", sd, v);
917 vfp_single_unpack(&vsn, v);
921 exceptions |= vfp_single_add(&vsd, &vsn, &vsp, fpscr);
933 static u32 vfp_single_fmac(
int sd,
int sn,
s32 m,
u32 fpscr)
935 return vfp_single_multiply_accumulate(sd, sn, m, fpscr, 0,
"fmac");
941 static u32 vfp_single_fnmac(
int sd,
int sn,
s32 m,
u32 fpscr)
943 return vfp_single_multiply_accumulate(sd, sn, m, fpscr,
NEG_MULTIPLY,
"fnmac");
949 static u32 vfp_single_fmsc(
int sd,
int sn,
s32 m,
u32 fpscr)
951 return vfp_single_multiply_accumulate(sd, sn, m, fpscr,
NEG_SUBTRACT,
"fmsc");
957 static u32 vfp_single_fnmsc(
int sd,
int sn,
s32 m,
u32 fpscr)
965 static u32 vfp_single_fmul(
int sd,
int sn,
s32 m,
u32 fpscr)
971 pr_debug(
"VFP: s%u = %08x\n", sn, n);
973 vfp_single_unpack(&vsn, n);
975 vfp_single_normalise_denormal(&vsn);
977 vfp_single_unpack(&vsm, m);
979 vfp_single_normalise_denormal(&vsm);
981 exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr);
988 static u32 vfp_single_fnmul(
int sd,
int sn,
s32 m,
u32 fpscr)
994 pr_debug(
"VFP: s%u = %08x\n", sn, n);
996 vfp_single_unpack(&vsn, n);
998 vfp_single_normalise_denormal(&vsn);
1000 vfp_single_unpack(&vsm, m);
1002 vfp_single_normalise_denormal(&vsm);
1004 exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr);
1012 static u32 vfp_single_fadd(
int sd,
int sn,
s32 m,
u32 fpscr)
1018 pr_debug(
"VFP: s%u = %08x\n", sn, n);
1023 vfp_single_unpack(&vsn, n);
1025 vfp_single_normalise_denormal(&vsn);
1027 vfp_single_unpack(&vsm, m);
1029 vfp_single_normalise_denormal(&vsm);
1031 exceptions = vfp_single_add(&vsd, &vsn, &vsm, fpscr);
1039 static u32 vfp_single_fsub(
int sd,
int sn,
s32 m,
u32 fpscr)
1050 static u32 vfp_single_fdiv(
int sd,
int sn,
s32 m,
u32 fpscr)
1057 pr_debug(
"VFP: s%u = %08x\n", sn, n);
1059 vfp_single_unpack(&vsn, n);
1060 vfp_single_unpack(&vsm, m);
1064 tn = vfp_single_type(&vsn);
1065 tm = vfp_single_type(&vsm);
1083 if (tm & tn & (VFP_INFINITY|VFP_ZERO))
1089 if (tn & VFP_INFINITY)
1101 if (tm & VFP_INFINITY || tn & VFP_ZERO)
1104 if (tn & VFP_DENORMAL)
1105 vfp_single_normalise_denormal(&vsn);
1106 if (tm & VFP_DENORMAL)
1107 vfp_single_normalise_denormal(&vsm);
1129 exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr);
1135 exceptions = vfp_propagate_nan(&vsd, &vsm, &vsn, fpscr);
1151 vfp_put_float(vfp_single_pack(&vfp_single_default_qnan), sd);
1155 static struct op fops[16] = {
1167 #define FREG_BANK(x) ((x) & 0x18)
1168 #define FREG_IDX(x) ((x) & 7)
1177 unsigned int vecitr, veclen, vecstride;
1204 pr_debug(
"VFP: vecstride=%u veclen=%u\n", vecstride,
1217 pr_debug(
"VFP: itr%d (%c%u) = op[%u] (s%u=%08x)\n",
1221 pr_debug(
"VFP: itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)\n",
1225 except = fop->
fn(dest, sn, m, fpscr);
1226 pr_debug(
"VFP: itr%d: exceptions=%08x\n",
1229 exceptions |= except;