arm64: fpsimd: avoid restoring fpcr if the contents haven't changed
authorWill Deacon <will.deacon@arm.com>
Thu, 10 Jul 2014 11:40:09 +0000 (12:40 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Fri, 18 Jul 2014 09:21:17 +0000 (10:21 +0100)
Writing to the FPCR is commonly implemented as a self-synchronising
operation in the CPU, so avoid writing to the register when the saved
value matches that in the hardware already.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/fpsimdmacros.h

index 768414d55e642f461788c0a031e1749c83cfac86..007618b8188c0844831cd8f0255caa2bb170e09d 100644 (file)
        str     w\tmpnr, [\state, #16 * 2 + 4]
 .endm
 
+.macro fpsimd_restore_fpcr state, tmp
+       /*
+        * Writes to fpcr may be self-synchronising, so avoid restoring
+        * the register if it hasn't changed.
+        */
+       mrs     \tmp, fpcr
+       cmp     \tmp, \state
+       b.eq    9999f
+       msr     fpcr, \state
+9999:
+.endm
+
+/* Clobbers \state */
 .macro fpsimd_restore state, tmpnr
        ldp     q0, q1, [\state, #16 * 0]
        ldp     q2, q3, [\state, #16 * 2]
@@ -60,7 +73,7 @@
        ldr     w\tmpnr, [\state, #16 * 2]
        msr     fpsr, x\tmpnr
        ldr     w\tmpnr, [\state, #16 * 2 + 4]
-       msr     fpcr, x\tmpnr
+       fpsimd_restore_fpcr x\tmpnr, \state
 .endm
 
 .altmacro
@@ -84,7 +97,7 @@
 .macro fpsimd_restore_partial state, tmpnr1, tmpnr2
        ldp     w\tmpnr1, w\tmpnr2, [\state]
        msr     fpsr, x\tmpnr1
-       msr     fpcr, x\tmpnr2
+       fpsimd_restore_fpcr x\tmpnr2, x\tmpnr1
        adr     x\tmpnr1, 0f
        ldr     w\tmpnr2, [\state, #8]
        add     \state, \state, x\tmpnr2, lsl #4