33 #include <linux/kernel.h>
34 #include <linux/bitops.h>
36 #include <asm/div64.h>
42 static struct vfp_double vfp_double_default_qnan = {
50 pr_debug(
"VFP: %s: sign=%d exponent=%d significand=%016llx\n",
54 static void vfp_double_normalise_denormal(
struct vfp_double *vd)
60 vfp_double_dump(
"normalise_denormal: in", vd);
67 vfp_double_dump(
"normalise_denormal: out", vd);
76 vfp_double_dump(
"pack: in", vd);
95 shift = 32 - fls(significand >> 32);
97 shift = 64 - fls(significand);
100 significand <<= shift;
106 vfp_double_dump(
"pack: normalised", vd);
112 underflow = exponent < 0;
114 significand = vfp_shiftright64jamming(significand, -exponent);
119 vfp_double_dump(
"pack: tiny number", vd);
133 if ((significand & (1ULL << (VFP_DOUBLE_LOW_BITS + 1))) == 0)
140 pr_debug(
"VFP: rounding increment = 0x%08llx\n", incr);
145 if ((significand + incr) < significand) {
147 significand = (significand >> 1) | (significand & 1);
152 vfp_double_dump(
"pack: overflow", vd);
171 if (exponent >= 2046) {
183 if (exponent || significand > 0x8000000000000000ULL)
192 vfp_double_dump(
"pack: final", vd);
194 s64 d = vfp_double_pack(vd);
195 pr_debug(
"VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func,
213 tn = vfp_double_type(vdn);
216 tm = vfp_double_type(vdm);
222 nan = &vfp_double_default_qnan;
256 static u32 vfp_double_fcpy(
int dd,
int unused,
int dm,
u32 fpscr)
262 static u32 vfp_double_fneg(
int dd,
int unused,
int dm,
u32 fpscr)
268 static u32 vfp_double_fsqrt(
int dd,
int unused,
int dm,
u32 fpscr)
274 tm = vfp_double_type(&vdm);
279 ret = vfp_propagate_nan(vdp, &vdm,
NULL, fpscr);
280 else if (vdm.
sign == 0) {
286 vdp = &vfp_double_default_qnan;
303 vfp_double_normalise_denormal(&vdm);
311 vfp_double_dump(
"sqrt", &vdm);
320 vfp_double_dump(
"sqrt estimate1", &vdd);
325 vfp_double_dump(
"sqrt estimate2", &vdd);
334 u64 termh, terml, remh, reml;
338 while ((
s64)remh < 0) {
342 add128(&remh, &reml, remh, reml, termh, terml);
358 static u32 vfp_compare(
int dd,
int signal_on_qnan,
int dm,
u32 fpscr)
419 static u32 vfp_double_fcmp(
int dd,
int unused,
int dm,
u32 fpscr)
421 return vfp_compare(dd, 0, dm, fpscr);
424 static u32 vfp_double_fcmpe(
int dd,
int unused,
int dm,
u32 fpscr)
426 return vfp_compare(dd, 1, dm, fpscr);
429 static u32 vfp_double_fcmpz(
int dd,
int unused,
int dm,
u32 fpscr)
434 static u32 vfp_double_fcmpez(
int dd,
int unused,
int dm,
u32 fpscr)
439 static u32 vfp_double_fcvts(
int sd,
int unused,
int dm,
u32 fpscr)
448 tm = vfp_double_type(&vdm);
456 if (tm & VFP_DENORMAL)
457 vfp_double_normalise_denormal(&vdm);
460 vsd.significand = vfp_hi64to32jamming(vdm.
significand);
470 }
else if (tm & VFP_ZERO)
473 vsd.exponent = vdm.
exponent - (1023 - 127);
482 static u32 vfp_double_fuito(
int dd,
int unused,
int dm,
u32 fpscr)
494 static u32 vfp_double_fsito(
int dd,
int unused,
int dm,
u32 fpscr)
499 vdm.
sign = (m & 0x80000000) >> 16;
506 static u32 vfp_double_ftoui(
int sd,
int unused,
int dm,
u32 fpscr)
509 u32 d, exceptions = 0;
518 tm = vfp_double_type(&vdm);
519 if (tm & VFP_DENORMAL)
526 d = vdm.
sign ? 0 : 0xffffffff;
528 }
else if (vdm.
exponent >= 1023 - 1) {
529 int shift = 1023 + 63 - vdm.
exponent;
539 incr = 0x8000000000000000ULL;
548 if ((rem + incr) < rem) {
573 pr_debug(
"VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
580 static u32 vfp_double_ftouiz(
int sd,
int unused,
int dm,
u32 fpscr)
585 static u32 vfp_double_ftosi(
int sd,
int unused,
int dm,
u32 fpscr)
588 u32 d, exceptions = 0;
593 vfp_double_dump(
"VDM", &vdm);
598 tm = vfp_double_type(&vdm);
599 if (tm & VFP_DENORMAL)
605 }
else if (vdm.
exponent >= 1023 + 32) {
610 }
else if (vdm.
exponent >= 1023 - 1) {
611 int shift = 1023 + 63 - vdm.
exponent;
618 incr = 0x8000000000000000ULL;
627 if ((rem + incr) < rem && d < 0xffffffff)
629 if (d > 0x7fffffff + (vdm.
sign != 0)) {
630 d = 0x7fffffff + (vdm.
sign != 0);
648 pr_debug(
"VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
655 static u32 vfp_double_ftosiz(
int dd,
int unused,
int dm,
u32 fpscr)
661 static struct op fops_ext[32] = {
690 tn = vfp_double_type(vdn);
691 tm = vfp_double_type(vdm);
702 vdp = &vfp_double_default_qnan;
709 }
else if (tn & VFP_INFINITY && tm &
VFP_NUMBER) {
718 return vfp_propagate_nan(vdd, vdn, vdm, fpscr);
733 pr_info(
"VFP: bad FP values in %s\n", __func__);
734 vfp_double_dump(
"VDN", vdn);
735 vfp_double_dump(
"VDM", vdm);
754 return vfp_double_fadd_nonnumber(vdd, vdn, vdm, fpscr);
767 m_sig = vfp_shiftright64jamming(vdm->
significand, exp_diff);
774 if ((
s64)m_sig < 0) {
777 }
else if (m_sig == 0) {
793 vfp_double_dump(
"VDN", vdn);
794 vfp_double_dump(
"VDM", vdm);
805 pr_debug(
"VFP: swapping M <-> N\n");
815 return vfp_propagate_nan(vdd, vdn, vdm, fpscr);
817 *vdd = vfp_double_default_qnan;
843 vfp_double_dump(
"VDD", vdd);
847 #define NEG_MULTIPLY (1 << 0)
848 #define NEG_SUBTRACT (1 << 1)
851 vfp_double_multiply_accumulate(
int dd,
int dn,
int dm,
u32 fpscr,
u32 negate,
char *
func)
858 vfp_double_normalise_denormal(&vdn);
862 vfp_double_normalise_denormal(&vdm);
864 exceptions = vfp_double_multiply(&vdp, &vdn, &vdm, fpscr);
872 exceptions |= vfp_double_add(&vdd, &vdn, &vdp, fpscr);
884 static u32 vfp_double_fmac(
int dd,
int dn,
int dm,
u32 fpscr)
886 return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, 0,
"fmac");
892 static u32 vfp_double_fnmac(
int dd,
int dn,
int dm,
u32 fpscr)
894 return vfp_double_multiply_accumulate(dd, dn, dm, fpscr,
NEG_MULTIPLY,
"fnmac");
900 static u32 vfp_double_fmsc(
int dd,
int dn,
int dm,
u32 fpscr)
902 return vfp_double_multiply_accumulate(dd, dn, dm, fpscr,
NEG_SUBTRACT,
"fmsc");
908 static u32 vfp_double_fnmsc(
int dd,
int dn,
int dm,
u32 fpscr)
916 static u32 vfp_double_fmul(
int dd,
int dn,
int dm,
u32 fpscr)
923 vfp_double_normalise_denormal(&vdn);
927 vfp_double_normalise_denormal(&vdm);
929 exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr);
936 static u32 vfp_double_fnmul(
int dd,
int dn,
int dm,
u32 fpscr)
943 vfp_double_normalise_denormal(&vdn);
947 vfp_double_normalise_denormal(&vdm);
949 exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr);
958 static u32 vfp_double_fadd(
int dd,
int dn,
int dm,
u32 fpscr)
965 vfp_double_normalise_denormal(&vdn);
969 vfp_double_normalise_denormal(&vdm);
971 exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr);
979 static u32 vfp_double_fsub(
int dd,
int dn,
int dm,
u32 fpscr)
986 vfp_double_normalise_denormal(&vdn);
990 vfp_double_normalise_denormal(&vdm);
997 exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr);
1005 static u32 vfp_double_fdiv(
int dd,
int dn,
int dm,
u32 fpscr)
1016 tn = vfp_double_type(&vdn);
1017 tm = vfp_double_type(&vdm);
1035 if (tm & tn & (VFP_INFINITY|VFP_ZERO))
1041 if (tn & VFP_INFINITY)
1053 if (tm & VFP_INFINITY || tn & VFP_ZERO)
1056 if (tn & VFP_DENORMAL)
1057 vfp_double_normalise_denormal(&vdn);
1058 if (tm & VFP_DENORMAL)
1059 vfp_double_normalise_denormal(&vdm);
1072 u64 termh, terml, remh, reml;
1075 while ((
s64)remh < 0) {
1084 exceptions = vfp_propagate_nan(&vdd, &vdn, &vdm, fpscr);
1090 exceptions = vfp_propagate_nan(&vdd, &vdm, &vdn, fpscr);
1110 static struct op fops[16] = {
1122 #define FREG_BANK(x) ((x) & 0x0c)
1123 #define FREG_IDX(x) ((x) & 3)
1132 unsigned int vecitr, veclen, vecstride;
1165 pr_debug(
"VFP: vecstride=%u veclen=%u\n", vecstride,
1177 pr_debug(
"VFP: itr%d (%c%u) = op[%u] (d%u)\n",
1179 type, dest, dn, dm);
1181 pr_debug(
"VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n",
1185 except = fop->
fn(dest, dn, dm, fpscr);
1186 pr_debug(
"VFP: itr%d: exceptions=%08x\n",
1189 exceptions |= except;