Rev 286 | Rev 429 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
/**************************************************************************** __________ __ ___.* Open \______ \ ____ ____ | | _\_ |__ _______ ___* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \* \/ \/ \/ \/ \/* $Id$** Copyright (C) 2006 Free Software Foundation, Inc.* This file was originally part of the GNU C Library* Contributed to glibc by MontaVista Software, Inc. (written by Nicolas Pitre)* Adapted for Rockbox by Daniel Ankers** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version 2* of the License, or (at your option) any later version.** This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY* KIND, either express or implied.*****************************************************************************/#define ASM_FILE#include "global.h"/* ARMv4T doesn't switch the T bit when popping pc directly, we must use BX */.macro ldmpc cond="", order="ia", regs#if ARM_ARCH == 4 && defined(USE_THUMB)ldm\cond\order sp!, { \regs, lr }bx\cond lr#elseldm\cond\order sp!, { \regs, pc }#endif.endm.macro ldrpc cond=""#if ARM_ARCH == 4 && defined(USE_THUMB)ldr\cond lr, [sp], #4bx\cond lr#elseldr\cond pc, [sp], #4#endif.endm/** Endian independent macros for shifting bytes within registers.*/#ifndef __ARMEB__#define pull lsr#define push lsl#else#define pull lsl#define push lsr#endif.text/** Prototype: void *memmove(void *dest, const void *src, size_t n);** Note:** If the memory regions don't overlap, we simply branch to memcpy which is* normally a bit faster. Otherwise the copy is done going downwards.*/.section .icode,"ax",%progbits.align 2.global memmove.type memmove,%functionmemmove:subs ip, r0, r1cmphi r2, ipbls memcpystmfd sp!, {r0, r4, lr}add r1, r1, r2add r0, r0, r2subs r2, r2, #4blt 8fands ip, r0, #3bne 9fands ip, r1, #3bne 10f1: subs r2, r2, #(28)stmfd sp!, {r5 - r8}blt 5f2:3:4: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}subs r2, r2, #32stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}bge 3b5: ands ip, r2, #28rsb ip, ip, #32addne pc, pc, ip @ C is always clear hereb 7f6: nopldr r3, [r1, #-4]!ldr r4, [r1, #-4]!ldr r5, [r1, #-4]!ldr r6, [r1, #-4]!ldr r7, [r1, #-4]!ldr r8, [r1, #-4]!ldr lr, [r1, #-4]!add pc, pc, ipnopnopstr r3, [r0, #-4]!str r4, [r0, #-4]!str r5, [r0, #-4]!str r6, [r0, #-4]!str r7, [r0, #-4]!str r8, [r0, #-4]!str lr, [r0, #-4]!7: ldmfd sp!, {r5 - r8}8: movs r2, r2, lsl #31ldrneb r3, [r1, #-1]!ldrcsb r4, [r1, #-1]!ldrcsb ip, [r1, #-1]strneb r3, [r0, #-1]!strcsb r4, [r0, #-1]!strcsb ip, [r0, #-1]ldmpc regs="r0, r4"9: cmp ip, #2ldrgtb r3, [r1, #-1]!ldrgeb r4, [r1, #-1]!ldrb lr, [r1, #-1]!strgtb r3, [r0, #-1]!strgeb r4, [r0, #-1]!subs r2, r2, ipstrb lr, [r0, #-1]!blt 8bands ip, r1, #3beq 1b10: bic r1, r1, #3cmp ip, #2ldr r3, [r1, #0]beq 17fblt 18f.macro backward_copy_shift push pullsubs r2, r2, #28blt 14f11: stmfd sp!, {r5 - r9}12:13: ldmdb r1!, {r7, r8, r9, ip}mov lr, r3, push #\pushsubs r2, r2, #32ldmdb r1!, {r3, r4, r5, r6}orr lr, lr, ip, pull #\pullmov ip, ip, push #\pushorr ip, ip, r9, pull #\pullmov r9, r9, push #\pushorr r9, r9, r8, pull #\pullmov r8, r8, push #\pushorr r8, r8, r7, pull #\pullmov r7, r7, push #\pushorr r7, r7, r6, pull #\pullmov r6, r6, push #\pushorr r6, r6, r5, pull #\pullmov r5, r5, push #\pushorr r5, r5, r4, pull #\pullmov r4, r4, push #\pushorr r4, r4, r3, pull #\pullstmdb r0!, {r4 - r9, ip, lr}bge 12bldmfd sp!, {r5 - r9}14: ands ip, r2, #28beq 16f15: mov lr, r3, push #\pushldr r3, [r1, #-4]!subs ip, ip, #4orr lr, lr, r3, pull #\pullstr lr, [r0, #-4]!bgt 15b16: add r1, r1, #(\pull / 8)b 8b.endmbackward_copy_shift push=8 pull=2417: backward_copy_shift push=16 pull=1618: backward_copy_shift push=24 pull=8