Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* memmove.S: Simple memmove implementation.
0003  *
0004  * Copyright (C) 1997, 2004 David S. Miller (davem@redhat.com)
0005  * Copyright (C) 1996, 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz)
0006  */
0007 
0008 #include <linux/linkage.h>
0009 #include <asm/export.h>
0010 
0011     .text
0012 ENTRY(memmove) /* o0=dst o1=src o2=len */
0013     brz,pn      %o2, 99f
0014      mov        %o0, %g1
0015 
0016     cmp     %o0, %o1
0017     bleu,pt     %xcc, 2f
0018      add        %o1, %o2, %g7
0019     cmp     %g7, %o0
0020     bleu,pt     %xcc, memcpy
0021      add        %o0, %o2, %o5
0022     sub     %g7, 1, %o1
0023 
0024     sub     %o5, 1, %o0
0025 1:  ldub        [%o1], %g7
0026     subcc       %o2, 1, %o2
0027     sub     %o1, 1, %o1
0028     stb     %g7, [%o0]
0029     bne,pt      %icc, 1b
0030      sub        %o0, 1, %o0
0031 99:
0032     retl
0033      mov        %g1, %o0
0034 
0035     /* We can't just call memcpy for these memmove cases.  On some
0036      * chips the memcpy uses cache initializing stores and when dst
0037      * and src are close enough, those can clobber the source data
0038      * before we've loaded it in.
0039      */
0040 2:  or      %o0, %o1, %g7
0041     or      %o2, %g7, %g7
0042     andcc       %g7, 0x7, %g0
0043     bne,pn      %xcc, 4f
0044      nop
0045 
0046 3:  ldx     [%o1], %g7
0047     add     %o1, 8, %o1
0048     subcc       %o2, 8, %o2
0049     add     %o0, 8, %o0
0050     bne,pt      %icc, 3b
0051      stx        %g7, [%o0 - 0x8]
0052     ba,a,pt     %xcc, 99b
0053 
0054 4:  ldub        [%o1], %g7
0055     add     %o1, 1, %o1
0056     subcc       %o2, 1, %o2
0057     add     %o0, 1, %o0
0058     bne,pt      %icc, 4b
0059      stb        %g7, [%o0 - 0x1]
0060     ba,a,pt     %xcc, 99b
0061 ENDPROC(memmove)
0062 EXPORT_SYMBOL(memmove)