[ARM] 3750/3: Fix double VFP emulation for EABI kernels

Patch from Daniel Jacobowitz

vfp_put_double didn't work in a CONFIG_AEABI kernel. By swapping
the arguments, we arrange for them to be in the same place regardless
of ABI. I made the same change to vfp_put_float for consistency.

Signed-off-by: Daniel Jacobowitz <dan@codesourcery.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Daniel Jacobowitz and committed by Russell King 0355b3e0 dc709bd1

+27 -33
+2 -8
arch/arm/vfp/vfp.h
··· 156 }; 157 158 extern s32 vfp_get_float(unsigned int reg); 159 - extern void vfp_put_float(unsigned int reg, s32 val); 160 161 /* 162 * VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa ··· 267 */ 268 #define VFP_REG_ZERO 16 269 extern u64 vfp_get_double(unsigned int reg); 270 - extern void vfp_put_double(unsigned int reg, u64 val); 271 272 #define VFP_DOUBLE_MANTISSA_BITS (52) 273 #define VFP_DOUBLE_EXPONENT_BITS (11) ··· 340 } 341 342 u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func); 343 - 344 - /* 345 - * System registers 346 - */ 347 - extern u32 vfp_get_sys(unsigned int reg); 348 - extern void vfp_put_sys(unsigned int reg, u32 val); 349 350 u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); 351
··· 156 }; 157 158 extern s32 vfp_get_float(unsigned int reg); 159 + extern void vfp_put_float(s32 val, unsigned int reg); 160 161 /* 162 * VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa ··· 267 */ 268 #define VFP_REG_ZERO 16 269 extern u64 vfp_get_double(unsigned int reg); 270 + extern void vfp_put_double(u64 val, unsigned int reg); 271 272 #define VFP_DOUBLE_MANTISSA_BITS (52) 273 #define VFP_DOUBLE_EXPONENT_BITS (11) ··· 340 } 341 342 u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func); 343 344 u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); 345
+10 -10
arch/arm/vfp/vfpdouble.c
··· 195 s64 d = vfp_double_pack(vd); 196 pr_debug("VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func, 197 dd, d, exceptions); 198 - vfp_put_double(dd, d); 199 } 200 return exceptions; 201 } ··· 250 */ 251 static u32 vfp_double_fabs(int dd, int unused, int dm, u32 fpscr) 252 { 253 - vfp_put_double(dd, vfp_double_packed_abs(vfp_get_double(dm))); 254 return 0; 255 } 256 257 static u32 vfp_double_fcpy(int dd, int unused, int dm, u32 fpscr) 258 { 259 - vfp_put_double(dd, vfp_get_double(dm)); 260 return 0; 261 } 262 263 static u32 vfp_double_fneg(int dd, int unused, int dm, u32 fpscr) 264 { 265 - vfp_put_double(dd, vfp_double_packed_negate(vfp_get_double(dm))); 266 return 0; 267 } 268 ··· 287 vdp = &vfp_double_default_qnan; 288 ret = FPSCR_IOC; 289 } 290 - vfp_put_double(dd, vfp_double_pack(vdp)); 291 return ret; 292 } 293 ··· 476 return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fcvts"); 477 478 pack_nan: 479 - vfp_put_float(sd, vfp_single_pack(&vsd)); 480 return exceptions; 481 } 482 ··· 573 574 pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 575 576 - vfp_put_float(sd, d); 577 578 return exceptions; 579 } ··· 648 649 pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 650 651 - vfp_put_float(sd, (s32)d); 652 653 return exceptions; 654 } ··· 1084 vdn_nan: 1085 exceptions = vfp_propagate_nan(&vdd, &vdn, &vdm, fpscr); 1086 pack: 1087 - vfp_put_double(dd, vfp_double_pack(&vdd)); 1088 return exceptions; 1089 1090 vdm_nan: ··· 1104 goto pack; 1105 1106 invalid: 1107 - vfp_put_double(dd, vfp_double_pack(&vfp_double_default_qnan)); 1108 return FPSCR_IOC; 1109 } 1110
··· 195 s64 d = vfp_double_pack(vd); 196 pr_debug("VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func, 197 dd, d, exceptions); 198 + vfp_put_double(d, dd); 199 } 200 return exceptions; 201 } ··· 250 */ 251 static u32 vfp_double_fabs(int dd, int unused, int dm, u32 fpscr) 252 { 253 + vfp_put_double(vfp_double_packed_abs(vfp_get_double(dm)), dd); 254 return 0; 255 } 256 257 static u32 vfp_double_fcpy(int dd, int unused, int dm, u32 fpscr) 258 { 259 + vfp_put_double(vfp_get_double(dm), dd); 260 return 0; 261 } 262 263 static u32 vfp_double_fneg(int dd, int unused, int dm, u32 fpscr) 264 { 265 + vfp_put_double(vfp_double_packed_negate(vfp_get_double(dm)), dd); 266 return 0; 267 } 268 ··· 287 vdp = &vfp_double_default_qnan; 288 ret = FPSCR_IOC; 289 } 290 + vfp_put_double(vfp_double_pack(vdp), dd); 291 return ret; 292 } 293 ··· 476 return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fcvts"); 477 478 pack_nan: 479 + vfp_put_float(vfp_single_pack(&vsd), sd); 480 return exceptions; 481 } 482 ··· 573 574 pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 575 576 + vfp_put_float(d, sd); 577 578 return exceptions; 579 } ··· 648 649 pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 650 651 + vfp_put_float((s32)d, sd); 652 653 return exceptions; 654 } ··· 1084 vdn_nan: 1085 exceptions = vfp_propagate_nan(&vdd, &vdn, &vdm, fpscr); 1086 pack: 1087 + vfp_put_double(vfp_double_pack(&vdd), dd); 1088 return exceptions; 1089 1090 vdm_nan: ··· 1104 goto pack; 1105 1106 invalid: 1107 + vfp_put_double(vfp_double_pack(&vfp_double_default_qnan), dd); 1108 return FPSCR_IOC; 1109 } 1110
+5 -5
arch/arm/vfp/vfphw.S
··· 178 179 .globl vfp_put_float 180 vfp_put_float: 181 - add pc, pc, r0, lsl #3 182 mov r0, r0 183 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 184 - mcr p10, 0, r1, c\dr, c0, 0 @ fmsr r0, s0 185 mov pc, lr 186 - mcr p10, 0, r1, c\dr, c0, 4 @ fmsr r0, s1 187 mov pc, lr 188 .endr 189 ··· 203 204 .globl vfp_put_double 205 vfp_put_double: 206 - add pc, pc, r0, lsl #3 207 mov r0, r0 208 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 209 - fmdrr d\dr, r1, r2 210 mov pc, lr 211 .endr
··· 178 179 .globl vfp_put_float 180 vfp_put_float: 181 + add pc, pc, r1, lsl #3 182 mov r0, r0 183 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 184 + mcr p10, 0, r0, c\dr, c0, 0 @ fmsr r0, s0 185 mov pc, lr 186 + mcr p10, 0, r0, c\dr, c0, 4 @ fmsr r0, s1 187 mov pc, lr 188 .endr 189 ··· 203 204 .globl vfp_put_double 205 vfp_put_double: 206 + add pc, pc, r2, lsl #3 207 mov r0, r0 208 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 209 + fmdrr d\dr, r0, r1 210 mov pc, lr 211 .endr
+10 -10
arch/arm/vfp/vfpsingle.c
··· 200 s32 d = vfp_single_pack(vs); 201 pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func, 202 sd, d, exceptions); 203 - vfp_put_float(sd, d); 204 } 205 206 return exceptions; ··· 257 */ 258 static u32 vfp_single_fabs(int sd, int unused, s32 m, u32 fpscr) 259 { 260 - vfp_put_float(sd, vfp_single_packed_abs(m)); 261 return 0; 262 } 263 264 static u32 vfp_single_fcpy(int sd, int unused, s32 m, u32 fpscr) 265 { 266 - vfp_put_float(sd, m); 267 return 0; 268 } 269 270 static u32 vfp_single_fneg(int sd, int unused, s32 m, u32 fpscr) 271 { 272 - vfp_put_float(sd, vfp_single_packed_negate(m)); 273 return 0; 274 } 275 ··· 333 vsp = &vfp_single_default_qnan; 334 ret = FPSCR_IOC; 335 } 336 - vfp_put_float(sd, vfp_single_pack(vsp)); 337 return ret; 338 } 339 ··· 517 return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd"); 518 519 pack_nan: 520 - vfp_put_double(dd, vfp_double_pack(&vdd)); 521 return exceptions; 522 } 523 ··· 613 614 pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 615 616 - vfp_put_float(sd, d); 617 618 return exceptions; 619 } ··· 692 693 pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 694 695 - vfp_put_float(sd, (s32)d); 696 697 return exceptions; 698 } ··· 1127 vsn_nan: 1128 exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr); 1129 pack: 1130 - vfp_put_float(sd, vfp_single_pack(&vsd)); 1131 return exceptions; 1132 1133 vsm_nan: ··· 1147 goto pack; 1148 1149 invalid: 1150 - vfp_put_float(sd, vfp_single_pack(&vfp_single_default_qnan)); 1151 return FPSCR_IOC; 1152 } 1153
··· 200 s32 d = vfp_single_pack(vs); 201 pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func, 202 sd, d, exceptions); 203 + vfp_put_float(d, sd); 204 } 205 206 return exceptions; ··· 257 */ 258 static u32 vfp_single_fabs(int sd, int unused, s32 m, u32 fpscr) 259 { 260 + vfp_put_float(vfp_single_packed_abs(m), sd); 261 return 0; 262 } 263 264 static u32 vfp_single_fcpy(int sd, int unused, s32 m, u32 fpscr) 265 { 266 + vfp_put_float(m, sd); 267 return 0; 268 } 269 270 static u32 vfp_single_fneg(int sd, int unused, s32 m, u32 fpscr) 271 { 272 + vfp_put_float(vfp_single_packed_negate(m), sd); 273 return 0; 274 } 275 ··· 333 vsp = &vfp_single_default_qnan; 334 ret = FPSCR_IOC; 335 } 336 + vfp_put_float(vfp_single_pack(vsp), sd); 337 return ret; 338 } 339 ··· 517 return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd"); 518 519 pack_nan: 520 + vfp_put_double(vfp_double_pack(&vdd), dd); 521 return exceptions; 522 } 523 ··· 613 614 pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 615 616 + vfp_put_float(d, sd); 617 618 return exceptions; 619 } ··· 692 693 pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 694 695 + vfp_put_float((s32)d, sd); 696 697 return exceptions; 698 } ··· 1127 vsn_nan: 1128 exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr); 1129 pack: 1130 + vfp_put_float(vfp_single_pack(&vsd), sd); 1131 return exceptions; 1132 1133 vsm_nan: ··· 1147 goto pack; 1148 1149 invalid: 1150 + vfp_put_float(vfp_single_pack(&vfp_single_default_qnan), sd); 1151 return FPSCR_IOC; 1152 } 1153