summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2013-07-16 23:19:05 +0000
committerandrew <andrew@FreeBSD.org>2013-07-16 23:19:05 +0000
commitba840962e3fa284766290d9cdab82a949fb9e192 (patch)
treefc158df124703a5ec56a038f59acfd33eee5b0ae /sys/arm
parent2bcd8f2bdde51839ef449bf6de4ef3c24d0e3639 (diff)
downloadFreeBSD-src-ba840962e3fa284766290d9cdab82a949fb9e192.zip
FreeBSD-src-ba840962e3fa284766290d9cdab82a949fb9e192.tar.gz
Fix vfp:
- We should check is_d32 to see howmany registers we have - In vfp_restore mark vfpscr as an output register Without the second part it appears we can return the incorrect value from vfp_bounce if the VFP condition flags are set as it may override the register holding the return value.
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/vfp.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/sys/arm/arm/vfp.c b/sys/arm/arm/vfp.c
index 212e4c3..b9dce13 100644
--- a/sys/arm/arm/vfp.c
+++ b/sys/arm/arm/vfp.c
@@ -202,21 +202,20 @@ vfp_restore(struct vfp_state *vfpsave)
* form ldcl<c>, and similar for stcleq.
*/
#ifdef __clang__
-#define ldcleq "ldcleq"
-#define stcleq "stcleq"
+#define ldclne "ldclne"
+#define stclne "stclne"
#else
-#define ldcleq "ldceql"
-#define stcleq "stceql"
+#define ldclne "ldcnel"
+#define stclne "stcnel"
#endif
if (vfpsave) {
- __asm __volatile("ldc p10, c0, [%0], #128\n" /* d0-d15 */
- "cmp %0, #0\n" /* -D16 or -D32? */
- ldcleq" p11, c0, [%0], #128\n" /* d16-d31 */
- "addne %0, %0, #128\n" /* skip missing regs */
- "ldr %1, [%0]\n" /* set old vfpscr */
- "mcr p10, 7, %1, cr1, c0, 0\n"
- :: "r" (vfpsave), "r" (vfpscr), "r" (is_d32)
- : "cc");
+ __asm __volatile("ldc p10, c0, [%1], #128\n" /* d0-d15 */
+ "cmp %2, #0\n" /* -D16 or -D32? */
+ ldclne" p11, c0, [%1], #128\n" /* d16-d31 */
+ "addeq %1, %1, #128\n" /* skip missing regs */
+ "ldr %0, [%1]\n" /* set old vfpscr */
+ "mcr p10, 7, %0, cr1, c0, 0\n"
+ : "=&r" (vfpscr) : "r" (vfpsave), "r" (is_d32) : "cc");
PCPU_SET(vfpcthread, PCPU_GET(curthread));
}
}
@@ -238,12 +237,12 @@ vfp_store(struct vfp_state *vfpsave)
tmp = fmrx(VFPEXC); /* Is the vfp enabled? */
if (vfpsave && tmp & VFPEXC_EN) {
__asm __volatile("stc p11, c0, [%1], #128\n" /* d0-d15 */
- "cmp %0, #0\n" /* -D16 or -D32? */
- stcleq" p11, c0, [%1], #128\n" /* d16-d31 */
- "addne %1, %1, #128\n" /* skip missing regs */
+ "cmp %2, #0\n" /* -D16 or -D32? */
+ stclne" p11, c0, [%1], #128\n" /* d16-d31 */
+ "addeq %1, %1, #128\n" /* skip missing regs */
"mrc p10, 7, %0, cr1, c0, 0\n" /* fmxr(VFPSCR) */
"str %0, [%1]\n" /* save vfpscr */
- : "=&r" (vfpscr) : "r" (vfpsave), "r" (is_d32) : "cc");
+ : "=&r" (vfpscr) : "r" (vfpsave), "r" (is_d32) : "cc");
}
#undef ldcleq
#undef stcleq
OpenPOWER on IntegriCloud