Merge branch 'core/topology' of git://git.kernel.org/pub/scm/linux/kernel/git/tip...
[pandora-kernel.git] / arch / arm / lib / memzero.S
index abf2508..b8f79d8 100644 (file)
@@ -39,6 +39,9 @@ ENTRY(__memzero)
  */
        cmp     r1, #16                 @ 1 we can skip this chunk if we
        blt     4f                      @ 1 have < 16 bytes
+
+#if ! CALGN(1)+0
+
 /*
  * We need an extra register for this loop - save the return address and
  * use the LR
@@ -64,6 +67,47 @@ ENTRY(__memzero)
        stmneia r0!, {r2, r3, ip, lr}   @ 4
        ldr     lr, [sp], #4            @ 1
 
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+       stmfd   sp!, {r4-r7, lr}
+       mov     r4, r2
+       mov     r5, r2
+       mov     r6, r2
+       mov     r7, r2
+       mov     ip, r2
+       mov     lr, r2
+
+       cmp     r1, #96
+       andgts  ip, r0, #31
+       ble     3f
+
+       rsb     ip, ip, #32
+       sub     r1, r1, ip
+       movs    ip, ip, lsl #(32 - 4)
+       stmcsia r0!, {r4, r5, r6, r7}
+       stmmiia r0!, {r4, r5}
+       movs    ip, ip, lsl #2
+       strcs   r2, [r0], #4
+
+3:     subs    r1, r1, #64
+       stmgeia r0!, {r2-r7, ip, lr}
+       stmgeia r0!, {r2-r7, ip, lr}
+       bgt     3b
+       ldmeqfd sp!, {r4-r7, pc}
+
+       tst     r1, #32
+       stmneia r0!, {r2-r7, ip, lr}
+       tst     r1, #16
+       stmneia r0!, {r4-r7}
+       ldmfd   sp!, {r4-r7, lr}
+
+#endif
+
 4:     tst     r1, #8                  @ 1 8 bytes or more?
        stmneia r0!, {r2, r3}           @ 2
        tst     r1, #4                  @ 1 4 bytes or more?