aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/vfp
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/vfp')
-rw-r--r--arch/arm/vfp/vfpdouble.c29
-rw-r--r--arch/arm/vfp/vfphw.S6
-rw-r--r--arch/arm/vfp/vfpsingle.c9
3 files changed, 24 insertions, 20 deletions
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index 9b367a65cb4d..febd115dba28 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -588,6 +588,7 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr)
588 struct vfp_double vdm; 588 struct vfp_double vdm;
589 u32 d, exceptions = 0; 589 u32 d, exceptions = 0;
590 int rmode = fpscr & FPSCR_RMODE_MASK; 590 int rmode = fpscr & FPSCR_RMODE_MASK;
591 int tm;
591 592
592 vfp_double_unpack(&vdm, vfp_get_double(dm)); 593 vfp_double_unpack(&vdm, vfp_get_double(dm));
593 vfp_double_dump("VDM", &vdm); 594 vfp_double_dump("VDM", &vdm);
@@ -595,10 +596,14 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr)
595 /* 596 /*
596 * Do we have denormalised number? 597 * Do we have denormalised number?
597 */ 598 */
598 if (vfp_double_type(&vdm) & VFP_DENORMAL) 599 tm = vfp_double_type(&vdm);
600 if (tm & VFP_DENORMAL)
599 exceptions |= FPSCR_IDC; 601 exceptions |= FPSCR_IDC;
600 602
601 if (vdm.exponent >= 1023 + 32) { 603 if (tm & VFP_NAN) {
604 d = 0;
605 exceptions |= FPSCR_IOC;
606 } else if (vdm.exponent >= 1023 + 32) {
602 d = 0x7fffffff; 607 d = 0x7fffffff;
603 if (vdm.sign) 608 if (vdm.sign)
604 d = ~d; 609 d = ~d;
@@ -1122,9 +1127,9 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1122{ 1127{
1123 u32 op = inst & FOP_MASK; 1128 u32 op = inst & FOP_MASK;
1124 u32 exceptions = 0; 1129 u32 exceptions = 0;
1125 unsigned int dd = vfp_get_sd(inst); 1130 unsigned int dd = vfp_get_dd(inst);
1126 unsigned int dn = vfp_get_sn(inst); 1131 unsigned int dn = vfp_get_dn(inst);
1127 unsigned int dm = vfp_get_sm(inst); 1132 unsigned int dm = vfp_get_dm(inst);
1128 unsigned int vecitr, veclen, vecstride; 1133 unsigned int vecitr, veclen, vecstride;
1129 u32 (*fop)(int, int, s32, u32); 1134 u32 (*fop)(int, int, s32, u32);
1130 1135
@@ -1141,7 +1146,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1141 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, 1146 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
1142 (veclen >> FPSCR_LENGTH_BIT) + 1); 1147 (veclen >> FPSCR_LENGTH_BIT) + 1);
1143 1148
1144 fop = (op == FOP_EXT) ? fop_extfns[dn] : fop_fns[FOP_TO_IDX(op)]; 1149 fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)];
1145 if (!fop) 1150 if (!fop)
1146 goto invalid; 1151 goto invalid;
1147 1152
@@ -1149,17 +1154,13 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1149 u32 except; 1154 u32 except;
1150 1155
1151 if (op == FOP_EXT) 1156 if (op == FOP_EXT)
1152 pr_debug("VFP: itr%d (d%u.%u) = op[%u] (d%u.%u)\n", 1157 pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n",
1153 vecitr >> FPSCR_LENGTH_BIT, 1158 vecitr >> FPSCR_LENGTH_BIT,
1154 dd >> 1, dd & 1, dn, 1159 dd, dn, dm);
1155 dm >> 1, dm & 1);
1156 else 1160 else
1157 pr_debug("VFP: itr%d (d%u.%u) = (d%u.%u) op[%u] (d%u.%u)\n", 1161 pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n",
1158 vecitr >> FPSCR_LENGTH_BIT, 1162 vecitr >> FPSCR_LENGTH_BIT,
1159 dd >> 1, dd & 1, 1163 dd, dn, FOP_TO_IDX(op), dm);
1160 dn >> 1, dn & 1,
1161 FOP_TO_IDX(op),
1162 dm >> 1, dm & 1);
1163 1164
1164 except = fop(dd, dn, dm, fpscr); 1165 except = fop(dd, dn, dm, fpscr);
1165 pr_debug("VFP: itr%d: exceptions=%08x\n", 1166 pr_debug("VFP: itr%d: exceptions=%08x\n",
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index b7ed57e00cd4..a3f65b47aea9 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -189,11 +189,10 @@ vfp_put_float:
189 189
190 .globl vfp_get_double 190 .globl vfp_get_double
191vfp_get_double: 191vfp_get_double:
192 mov r0, r0, lsr #1
193 add pc, pc, r0, lsl #3 192 add pc, pc, r0, lsl #3
194 mov r0, r0 193 mov r0, r0
195 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 194 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
196 mrrc p10, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr 195 mrrc p11, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr
197 mov pc, lr 196 mov pc, lr
198 .endr 197 .endr
199 198
@@ -204,10 +203,9 @@ vfp_get_double:
204 203
205 .globl vfp_put_double 204 .globl vfp_put_double
206vfp_put_double: 205vfp_put_double:
207 mov r0, r0, lsr #1
208 add pc, pc, r0, lsl #3 206 add pc, pc, r0, lsl #3
209 mov r0, r0 207 mov r0, r0
210 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 208 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
211 mcrr p10, 1, r1, r2, c\dr @ fmrrd r1, r2, d\dr 209 mcrr p11, 1, r1, r2, c\dr @ fmdrr r1, r2, d\dr
212 mov pc, lr 210 mov pc, lr
213 .endr 211 .endr
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index 14dd696ddeb1..4ac27f193934 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -632,6 +632,7 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr)
632 struct vfp_single vsm; 632 struct vfp_single vsm;
633 u32 d, exceptions = 0; 633 u32 d, exceptions = 0;
634 int rmode = fpscr & FPSCR_RMODE_MASK; 634 int rmode = fpscr & FPSCR_RMODE_MASK;
635 int tm;
635 636
636 vfp_single_unpack(&vsm, m); 637 vfp_single_unpack(&vsm, m);
637 vfp_single_dump("VSM", &vsm); 638 vfp_single_dump("VSM", &vsm);
@@ -639,10 +640,14 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr)
639 /* 640 /*
640 * Do we have a denormalised number? 641 * Do we have a denormalised number?
641 */ 642 */
643 tm = vfp_single_type(&vsm);
642 if (vfp_single_type(&vsm) & VFP_DENORMAL) 644 if (vfp_single_type(&vsm) & VFP_DENORMAL)
643 exceptions |= FPSCR_IDC; 645 exceptions |= FPSCR_IDC;
644 646
645 if (vsm.exponent >= 127 + 32) { 647 if (tm & VFP_NAN) {
648 d = 0;
649 exceptions |= FPSCR_IOC;
650 } else if (vsm.exponent >= 127 + 32) {
646 /* 651 /*
647 * m >= 2^31-2^7: invalid 652 * m >= 2^31-2^7: invalid
648 */ 653 */
@@ -1188,7 +1193,7 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr)
1188 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, 1193 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
1189 (veclen >> FPSCR_LENGTH_BIT) + 1); 1194 (veclen >> FPSCR_LENGTH_BIT) + 1);
1190 1195
1191 fop = (op == FOP_EXT) ? fop_extfns[sn] : fop_fns[FOP_TO_IDX(op)]; 1196 fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)];
1192 if (!fop) 1197 if (!fop)
1193 goto invalid; 1198 goto invalid;
1194 1199