+ mov r10, r6
+#endif
+
+/*
+ * Check to see if we will overwrite ourselves.
+ * r4 = final kernel address
+ * r5 = start of this image
+ * r9 = size of decompressed image
+ * r10 = end of this image, including bss/stack/malloc space if non XIP
+ * We basically want:
+ * r4 >= r10 -> OK
+ * r4 + image length <= r5 -> OK
+ */
+ cmp r4, r10
+ bhs wont_overwrite
+ add r10, r4, r9
+ cmp r10, r5
+ bls wont_overwrite
+
+/*
+ * Relocate ourselves past the end of the decompressed kernel.
+ * r5 = start of this image
+ * r6 = _edata
+ * r10 = end of the decompressed kernel
+ * Because we always copy ahead, we need to do it from the end and go
+ * backward in case the source and destination overlap.
+ */
+ /* Round up to next 256-byte boundary. */
+ add r10, r10, #256
+ bic r10, r10, #255
+
+ sub r9, r6, r5 @ size to copy
+ add r9, r9, #31 @ rounded up to a multiple
+ bic r9, r9, #31 @ ... of 32 bytes
+ add r6, r9, r5
+ add r9, r9, r10
+
+1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
+ cmp r6, r5
+ stmdb r9!, {r0 - r3, r10 - r12, lr}
+ bhi 1b
+
+ /* Preserve offset to relocated code. */
+ sub r6, r9, r6
+
+ bl cache_clean_flush
+
+ adr r0, BSYM(restart)
+ add r0, r0, r6
+ mov pc, r0
+
+wont_overwrite:
+/*
+ * If delta is zero, we are running at the address we were linked at.
+ * r0 = delta
+ * r2 = BSS start
+ * r3 = BSS end
+ * r4 = kernel execution address
+ * r7 = architecture ID
+ * r8 = atags pointer
+ * r11 = GOT start
+ * r12 = GOT end
+ * sp = stack pointer
+ */
+ teq r0, #0
+ beq not_relocated