arch: arm: lib: optimize memcpy for cortex-A15
Chandler Zhang [Fri, 15 Mar 2013 12:02:59 +0000 (20:02 +0800)]
The LDRD/STRD instruction is faster than LDM/STM on Cortex-A15.
Also optimized preload cache size for Cortex-A15.

Added USE_LDRDSTRD_OVER_LDMSTM to turn on LDRD/STRD optimization.
Added ARM_PLD_SIZE, default 32. Should set to 64 for Cortex-A15.

Bug 1185248

Change-Id: I4fa8c25bcd9b7823a11018817a4d17e3357ae681
Signed-off-by: Chandler Zhang <chazhang@nvidia.com>
Reviewed-on: http://git-master/r/212965
Reviewed-by: Riham Haidar <rhaidar@nvidia.com>
Tested-by: Riham Haidar <rhaidar@nvidia.com>

arch/arm/Kconfig
arch/arm/lib/copy_from_user.S
arch/arm/lib/copy_template.S
arch/arm/lib/copy_to_user.S
arch/arm/lib/memcpy.S

index 99822ba..6472d15 100644 (file)
@@ -1989,6 +1989,19 @@ config UACCESS_WITH_MEMCPY
          However, if the CPU data cache is using a write-allocate mode,
          this option is unlikely to provide any performance gain.
 
+config ARM_PLD_64BYTE
+       bool "Use 64-bit preload size for kernel memory copy"
+       depends on CPU_V7
+       help
+         Config preload size for memcpy, selecting this for Cortex-A15
+
+config USE_LDRDSTRD_OVER_LDMSTM
+       bool "Use 64-bit access instructions to optimize memory copy"
+       depends on CPU_V7
+       help
+         Cortex-A15 perform better when use LDRD/STRD to access memory.
+         Selecting this to optimize memory copy routines.
+
 config SECCOMP
        bool
        prompt "Enable seccomp to safely compute untrusted bytecode"
index 66a477a..317f5e3 100644 (file)
        stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
        .endm
 
+#ifdef CONFIG_USE_LDRDSTRD_OVER_LDMSTM
+       .macro cpy8w dst src reg1 reg2 abort
+       .irp offset, #0, #8, #16, #24
+       ldr1w \src, \reg1, \abort
+       ldr1w \src, \reg2, \abort
+       strd \reg1, \reg2, [\dst, \offset]
+       .endr
+       add \dst, \dst, #32
+       .endm
+#endif
+
        .macro str1b ptr reg cond=al abort
        str\cond\()b \reg, [\ptr], #1
        .endm
index 805e3f8..54c1296 100644 (file)
  *     in provided registers and increments 'ptr' past those words.
  *     The'abort' argument is used for fixup tables.
  *
+ * cpy8w dst src reg1 reg2 abort
+ *
+ *     This loads eight words starting from 'src' and stores them in 'dst'
+ *     The 'abort' argument is used for fixup tables.
+ *
  * ldr1b ptr reg cond abort
  *
  *     Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
@@ -66,7 +71,6 @@
  *     than one 32bit instruction in Thumb-2)
  */
 
-
                enter   r4, lr
 
                subs    r2, r2, #4
        CALGN(  add     pc, r4, ip              )
 
        PLD(    pld     [r1, #0]                )
+#if CONFIG_ARM_PLD_64BYTE
+2:     PLD(    cmp     r2, #32                 )
+       PLD(    blt     .32cpy                  )
+.64cpy:        PLD(    subs    r2, r2, #224            )
+       PLD(    pld     [r1, #60]               )
+       PLD(    blt     4f                      )
+       PLD(    pld     [r1, #124]              )
+       PLD(    pld     [r1, #188]              )
+3:     PLD(    pld     [r1, #252]              )
+#ifdef CONFIG_USE_LDRDSTRD_OVER_LDMSTM
+4:             cpy8w   r0, r1, r4, r5, abort = 20f
+               cpy8w   r0, r1, r4, r5, abort = 20f
+               subs    r2, r2, #64
+#else
+4:             ldr8w   r1, r3, r4, r5, r6, r7, r8, ip, lr, abort = 20f
+               str8w   r0, r3, r4, r5, r6, r7, r8, ip, lr, abort = 20f
+               ldr8w   r1, r3, r4, r5, r6, r7, r8, ip, lr, abort = 20f
+               subs    r2, r2, #64
+               str8w   r0, r3, r4, r5, r6, r7, r8, ip, lr, abort = 20f
+#endif
+               bge 3b
+       PLD(    cmn     r2, #192                )
+       PLD(    bge     4b                      )
+       PLD(    cmn     r2, #224                )
+       PLD(    blt     5f                      )
+#ifdef CONFIG_USE_LDRDSTRD_OVER_LDMSTM
+.32cpy:                cpy8w   r0, r1, r4, r5, abort = 20f
+#else
+.32cpy:                ldr8w   r1, r3, r4, r5, r6, r7, r8, ip, lr, abort = 20f
+               str8w   r0, r3, r4, r5, r6, r7, r8, ip, lr, abort = 20f
+#endif
+#else
 2:     PLD(    subs    r2, r2, #96             )
        PLD(    pld     [r1, #28]               )
        PLD(    blt     4f                      )
        PLD(    pld     [r1, #92]               )
 
 3:     PLD(    pld     [r1, #124]              )
+#ifdef CONFIG_USE_LDRDSTRD_OVER_LDMSTM
+4:             cpy8w   r0, r1, r4, r5, abort = 20f
+               subs    r2, r2, #32
+#else
 4:             ldr8w   r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
                subs    r2, r2, #32
                str8w   r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+#endif
                bge     3b
        PLD(    cmn     r2, #96                 )
        PLD(    bge     4b                      )
-
+#endif
 5:             ands    ip, r2, #28
                rsb     ip, ip, #32
 #if LDR1W_SHIFT > 0
index d066df6..185460f 100644 (file)
        str1w \ptr, \reg8, \abort
        .endm
 
+#ifdef CONFIG_USE_LDRDSTRD_OVER_LDMSTM
+       .macro cpy8w dst src reg1 reg2 abort
+       .irp offset, #0, #8, #16, #24
+       ldrd \reg1, \reg2, [\src, \offset]
+       str1w \dst, \reg1, \abort
+       str1w \dst, \reg2, \abort
+       .endr
+       add \src, \src, #32
+       .endm
+#endif
+
        .macro str1b ptr reg cond=al abort
        strusr  \reg, \ptr, 1, \cond, abort=\abort
        .endm
index a9b9e22..7782a37 100644 (file)
        stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
        .endm
 
+#ifdef CONFIG_USE_LDRDSTRD_OVER_LDMSTM
+       .macro cpy8w dst src reg1 reg2 abort
+       .irp offset, #0, #8, #16, #24
+       ldrd \reg1, \reg2, [\src, \offset]
+       strd \reg1, \reg2, [\dst, \offset]
+       .endr
+       add \src, \src, #32
+       add \dst, \dst, #32
+       .endm
+#endif
+
        .macro str1b ptr reg cond=al abort
        str\cond\()b \reg, [\ptr], #1
        .endm