1/* memcpy.S 2 * Copyright (C) 2003-2007 Analog Devices Inc., All Rights Reserved. 3 * 4 * This file is subject to the terms and conditions of the GNU Library General 5 * Public License. See the file "COPYING.LIB" in the main directory of this 6 * archive for more details. 7 * 8 * Non-LGPL License also available as part of VisualDSP++ 9 * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html 10 */ 11 12#include <sysdep.h> 13 14/* void *memcpy(void *dest, const void *src, size_t n); 15 * R0 = To Address (dest) (leave unchanged to form result) 16 * R1 = From Address (src) 17 * R2 = count 18 * 19 * Note: Favours word alignment 20 */ 21 22.text 23 24.align 2 25 26.weak _memcpy 27ENTRY(_memcpy) 28 [--SP] = P3; 29 P0 = R0; /* P0 = To address */ 30 P3 = R1; /* P3 = From Address */ 31 P2 = R2; /* P2 = count */ 32 CC = R2 <= 7(IU); 33 IF CC JUMP .Ltoo_small; 34 I0 = R1; 35 R3 = R1 | R0; /* OR addresses together */ 36 R3 <<= 30; /* check bottom two bits */ 37 CC = AZ; /* AZ set if zero. */ 38 IF !CC JUMP .Lbytes; /* Jump if addrs not aligned. */ 39 P1 = P2 >> 2; /* count = n/4 */ 40 P1 += -1; 41 R3 = 3; 42 R2 = R2 & R3; /* remainder */ 43 P2 = R2; /* set remainder */ 44 R1 = [I0++]; 45#if !defined(__WORKAROUND_AVOID_DAG1) 46 LSETUP (.Lquad_loop, .Lquad_loop) LC0=P1; 47.Lquad_loop: MNOP || [P0++] = R1 || R1 = [I0++]; 48#else 49 LSETUP (.Lquad_loop_s, .Lquad_loop_e) LC0=P1; 50.Lquad_loop_s: [P0++] = R1; 51.Lquad_loop_e: R1 = [I0++]; 52#endif 53 [P0++] = R1; 54 55 CC = P2 == 0; /* any remaining bytes? */ 56 P3 = I0; /* Ammend P3 for remaining copy */ 57 IF !CC JUMP .Lbytes; 58 P3 = [SP++]; 59 RTS; 60 61.Ltoo_small: 62 CC = P2 == 0; /* Check zero count */ 63 IF CC JUMP .Lfinished; /* very unlikely */ 64 65.Lbytes: 66 LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2; 67.Lbyte_loop_s: R1 = B[P3++](Z); 68.Lbyte_loop_e: B[P0++] = R1; 69 70.Lfinished: 71 P3 = [SP++]; 72 73 RTS; 74 75.size _memcpy,.-_memcpy 76 77libc_hidden_def (memcpy) 78