]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/arm/lib/copy_template.S
Merge branch 'x86-pat-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mv-sheeva.git] / arch / arm / lib / copy_template.S
index cab355c0c1f782d28fc7c074f5a08b1661fadc50..805e3f8fb00786f00f62820c57b02852ad043aaa 100644 (file)
  *  published by the Free Software Foundation.
  */
 
-/*
- * This can be used to enable code to cacheline align the source pointer.
- * Experiments on tested architectures (StrongARM and XScale) didn't show
- * this a worthwhile thing to do.  That might be different in the future.
- */
-//#define CALGN(code...)       code
-#define CALGN(code...)
-
 /*
  * Theory of operation
  * -------------------
  *
  *     Restore registers with the values previously saved with the
  *     'preserv' macro. Called upon code termination.
+ *
+ * LDR1W_SHIFT
+ * STR1W_SHIFT
+ *
+ *     Correction to be applied to the "ip" register when branching into
+ *     the ldr1w or str1w instructions (some of these macros may expand to
+ *     than one 32bit instruction in Thumb-2)
  */
 
 
@@ -82,7 +81,7 @@
                stmfd   sp!, {r5 - r8}
                blt     5f
 
-       CALGN(  ands    ip, r1, #31             )
+       CALGN(  ands    ip, r0, #31             )
        CALGN(  rsb     r3, ip, #32             )
        CALGN(  sbcnes  r4, r3, r2              )  @ C is always set here
        CALGN(  bcs     2f                      )
 
 5:             ands    ip, r2, #28
                rsb     ip, ip, #32
+#if LDR1W_SHIFT > 0
+               lsl     ip, ip, #LDR1W_SHIFT
+#endif
                addne   pc, pc, ip              @ C is always clear here
                b       7f
-6:             nop
+6:
+               .rept   (1 << LDR1W_SHIFT)
+               W(nop)
+               .endr
                ldr1w   r1, r3, abort=20f
                ldr1w   r1, r4, abort=20f
                ldr1w   r1, r5, abort=20f
                ldr1w   r1, r8, abort=20f
                ldr1w   r1, lr, abort=20f
 
+#if LDR1W_SHIFT < STR1W_SHIFT
+               lsl     ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
+#elif LDR1W_SHIFT > STR1W_SHIFT
+               lsr     ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
+#endif
                add     pc, pc, ip
                nop
-               nop
+               .rept   (1 << STR1W_SHIFT)
+               W(nop)
+               .endr
                str1w   r0, r3, abort=20f
                str1w   r0, r4, abort=20f
                str1w   r0, r5, abort=20f
                subs    r2, r2, #28
                blt     14f
 
-       CALGN(  ands    ip, r1, #31             )
+       CALGN(  ands    ip, r0, #31             )
        CALGN(  rsb     ip, ip, #32             )
        CALGN(  sbcnes  r4, ip, r2              )  @ C is always set here
        CALGN(  subcc   r2, r2, ip              )