summaryrefslogtreecommitdiffstats
path: root/bsps/arm/shared/start/bsp-start-memcpy.S
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/arm/shared/start/bsp-start-memcpy.S')
-rw-r--r--bsps/arm/shared/start/bsp-start-memcpy.S147
1 files changed, 147 insertions, 0 deletions
diff --git a/bsps/arm/shared/start/bsp-start-memcpy.S b/bsps/arm/shared/start/bsp-start-memcpy.S
new file mode 100644
index 0000000000..cb97eb47f8
--- /dev/null
+++ b/bsps/arm/shared/start/bsp-start-memcpy.S
@@ -0,0 +1,147 @@
+/**
+ * @file
+ *
+ * @brief bsp_start_memcpy() implementation.
+ */
+
+/*
+ * Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/asm.h>
+#include <rtems/system.h>
+#include <rtems/score/cpu.h>
+
+ .section ".bsp_start_text", "ax"
+
+#if defined(ARM_MULTILIB_ARCH_V4)
+
+DEFINE_FUNCTION_ARM(bsp_start_memcpy)
+
+ /* Return if dest == src */
+ cmp r0, r1
+#ifdef __thumb__
+ bxeq lr
+#else
+ moveq pc, lr
+#endif
+
+ /* Return if length is zero */
+ mov r3, #0
+ cmp r3, r2
+#ifdef __thumb__
+ bxeq lr
+#else
+ moveq pc, lr
+#endif
+
+ /* Save non-volatile registers */
+ push {r4-r8, lr}
+
+ /* Copy worker routine to stack */
+ adr ip, worker_begin
+ ldm ip, {r3-r8}
+ push {r3-r8}
+
+ /* Execute worker routine */
+ mov r3, #0
+ mov ip, sp
+ mov lr, pc
+#ifdef __thumb__
+ bx ip
+#else
+ mov pc, ip
+#endif
+
+ /* Restore stack and non-volatile registers */
+ add sp, sp, #24
+ pop {r4-r8, lr}
+
+ /* Return */
+#ifdef __thumb__
+ bx lr
+#else
+ mov pc, lr
+#endif
+
+worker_begin:
+
+ /* Worker routine */
+ ldr ip, [r1, r3]
+ str ip, [r0, r3]
+ add r3, r3, #4
+ cmp r3, r2
+ bcc worker_begin
+#ifdef __thumb__
+ bx lr
+#else
+ mov pc, lr
+#endif
+
+#elif defined(ARM_MULTILIB_ARCH_V7M)
+
+ .syntax unified
+
+ .align 2
+ .globl bsp_start_memcpy
+ .thumb
+ .thumb_func
+ .type bsp_start_memcpy, %function
+
+bsp_start_memcpy:
+
+ /* Return if dest == src */
+ cmp r0, r1
+ beq return
+
+ /* Return if length is zero */
+ movs r3, #0
+ cmp r3, r2
+ beq return
+
+ /* Save non-volatile registers */
+ push {r4-r7, lr}
+
+ /* Copy worker routine to stack */
+ adr r3, worker_begin
+ ldm r3, {r4-r7}
+ push {r4-r7}
+
+ /* Execute worker routine */
+ add r3, sp, #1
+ adds r2, r2, #3
+ bic r2, r2, #3
+ adds r2, r2, r1
+ blx r3
+
+ /* Restore stack and non-volatile registers */
+ add sp, sp, #16
+ pop {r4-r7, lr}
+
+return:
+
+ /* Return */
+ bx lr
+
+ .align 2
+
+worker_begin:
+
+ /* Worker routine */
+ ldr r3, [r1], #4
+ cmp r2, r1
+ str r3, [r0], #4
+ bne worker_begin
+ bx lr
+
+#endif /* defined(ARM_MULTILIB_ARCH_V7M) */