diff options
Diffstat (limited to 'arch/arm/vfp')
-rw-r--r-- | arch/arm/vfp/vfpdouble.c | 29 | ||||
-rw-r--r-- | arch/arm/vfp/vfphw.S | 6 | ||||
-rw-r--r-- | arch/arm/vfp/vfpsingle.c | 9 |
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 |
191 | vfp_get_double: | 191 | vfp_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 |
206 | vfp_put_double: | 205 | vfp_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 | ||