[BACK]Return to memcpy.S CVS log [TXT][DIR] Up to [local] / sys / lib / libkern / arch / sh

Annotation of sys/lib/libkern/arch/sh/memcpy.S, Revision 1.1.1.1

1.1       nbrk        1: /*     $NetBSD: memcpy.S,v 1.2 2006/04/22 23:53:47 uwe Exp $   */
                      2:
                      3: /*
                      4:  * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org>
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. The name of the author may not be used to endorse or promote products
                     16:  *    derived from this software without specific prior written permission.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
                     27:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     28:  */
                     29:
                     30: #include <machine/asm.h>
                     31:
                     32: #if defined(LIBC_SCCS) && !defined(lint)
                     33:        RCSID("$NetBSD: memcpy.S,v 1.2 2006/04/22 23:53:47 uwe Exp $")
                     34: #endif
                     35:
                     36: #if !defined(MEMCOPY) && !defined(MEMMOVE) && !defined(BCOPY)
                     37: #define MEMCOPY
                     38: #endif
                     39:
                     40: #if defined(MEMCOPY) || defined(MEMMOVE)
                     41: #define        REG_DST0        r3
                     42: #define        REG_SRC         r5
                     43: #define        REG_DST         r4
                     44: #else
                     45: #define        REG_SRC         r4
                     46: #define        REG_DST         r5
                     47: #endif
                     48:
                     49: #define        REG_LEN         r6
                     50:
                     51: #if defined(MEMCOPY)
                     52: ENTRY(memcpy)
                     53: #elif defined(MEMMOVE)
                     54: ENTRY(memmove)
                     55: #elif defined(BCOPY)
                     56: ENTRY(bcopy)
                     57: ALTENTRY(ovbcopy)
                     58: #endif
                     59: #ifdef REG_DST0
                     60:        mov     REG_DST,REG_DST0
                     61: #endif
                     62:        cmp/eq  REG_DST,REG_SRC /* if ( src == dst ) return; */
                     63:        bt/s    bcopy_return
                     64:        cmp/hi  REG_DST,REG_SRC
                     65:        bf/s    bcopy_overlap
                     66:
                     67:        mov     REG_SRC,r0
                     68:        xor     REG_DST,r0
                     69:        and     #3,r0
                     70:        mov     r0,r1
                     71:        tst     r0,r0           /* (src ^ dst) & 3         */
                     72:        bf/s    word_align
                     73:
                     74: longword_align:
                     75:        tst     REG_LEN,REG_LEN /* if ( len==0 ) return;   */
                     76:        bt/s    bcopy_return
                     77:
                     78:
                     79:        mov     REG_SRC,r0
                     80:        tst     #1,r0           /* if ( src & 1 )          */
                     81:        bt      1f
                     82:        mov.b   @REG_SRC+,r0    /*    *dst++ = *src++;     */
                     83:        add     #-1,REG_LEN
                     84:        mov.b   r0,@REG_DST
                     85:        add     #1,REG_DST
                     86: 1:
                     87:
                     88:
                     89:        mov     #1,r0
                     90:        cmp/hi  r0,REG_LEN      /* if ( (len > 1) &&       */
                     91:        bf/s    1f
                     92:        mov     REG_SRC,r0
                     93:        tst     #2,r0           /*      (src & 2) {        */
                     94:        bt      1f
                     95:        mov.w   @REG_SRC+,r0    /*        *((unsigned short*)dst)++ = *((unsigned short*)src)++; */
                     96:        add     #-2,REG_LEN     /*        len -= 2;                                              */
                     97:        mov.w   r0,@REG_DST
                     98:        add     #2,REG_DST      /* }                       */
                     99: 1:
                    100:
                    101:
                    102:        mov     #3,r1
                    103:        cmp/hi  r1,REG_LEN      /* while ( len > 3 ) {     */
                    104:        bf/s    no_align_delay
                    105:        tst     REG_LEN,REG_LEN
                    106: 2:
                    107:        mov.l   @REG_SRC+,r0    /*   *((unsigned long*)dst)++ = *((unsigned long*)src)++;        */
                    108:        add     #-4,REG_LEN     /*   len -= 4;                                                   */
                    109:        mov.l   r0,@REG_DST
                    110:        cmp/hi  r1,REG_LEN
                    111:        bt/s    2b
                    112:        add     #4,REG_DST      /* }                       */
                    113:
                    114:        bra     no_align_delay
                    115:        tst     REG_LEN,REG_LEN
                    116:
                    117:
                    118: word_align:
                    119:        mov     r1,r0
                    120:        tst     #1,r0
                    121:        bf/s    no_align_delay
                    122:        tst     REG_LEN,REG_LEN /* if ( len == 0 ) return; */
                    123:        bt      bcopy_return
                    124:
                    125:
                    126:        mov     REG_SRC,r0      /* if ( src & 1 )          */
                    127:        tst     #1,r0
                    128:        bt      1f
                    129:        mov.b   @REG_SRC+,r0    /*    *dst++ = *src++;     */
                    130:        add     #-1,REG_LEN
                    131:        mov.b   r0,@REG_DST
                    132:        add     #1,REG_DST
                    133: 1:
                    134:
                    135:
                    136:        mov     #1,r1
                    137:        cmp/hi  r1,REG_LEN      /* while ( len > 1 ) {     */
                    138:        bf/s    no_align_delay
                    139:        tst     REG_LEN,REG_LEN
                    140: 2:
                    141:        mov.w   @REG_SRC+,r0    /*   *((unsigned short*)dst)++ = *((unsigned short*)src)++;      */
                    142:        add     #-2,REG_LEN     /*   len -= 2;                                                   */
                    143:        mov.w   r0,@REG_DST
                    144:        cmp/hi  r1,REG_LEN
                    145:        bt/s    2b
                    146:        add     #2,REG_DST      /* }                       */
                    147:
                    148:
                    149: no_align:
                    150:        tst     REG_LEN,REG_LEN /* while ( len!= ) {       */
                    151: no_align_delay:
                    152:        bt      bcopy_return
                    153: 1:
                    154:        mov.b   @REG_SRC+,r0    /*    *dst++ = *src++;     */
                    155:        add     #-1,REG_LEN     /*    len--;               */
                    156:        mov.b   r0,@REG_DST
                    157:        tst     REG_LEN,REG_LEN
                    158:        bf/s    1b
                    159:        add     #1,REG_DST      /* }                       */
                    160: bcopy_return:
                    161:        rts
                    162: #ifdef REG_DST0
                    163:        mov     REG_DST0,r0
                    164: #else
                    165:        nop
                    166: #endif
                    167:
                    168:
                    169: bcopy_overlap:
                    170:        add     REG_LEN,REG_SRC
                    171:        add     REG_LEN,REG_DST
                    172:
                    173:        mov     REG_SRC,r0
                    174:        xor     REG_DST,r0
                    175:        and     #3,r0
                    176:        mov     r0,r1
                    177:        tst     r0,r0           /* (src ^ dst) & 3         */
                    178:        bf/s    ov_word_align
                    179:
                    180: ov_longword_align:
                    181:        tst     REG_LEN,REG_LEN /* if ( len==0 ) return;   */
                    182:        bt/s    bcopy_return
                    183:
                    184:
                    185:        mov     REG_SRC,r0
                    186:        tst     #1,r0           /* if ( src & 1 )          */
                    187:        bt      1f
                    188:        add     #-1,REG_SRC     /*    *--dst = *--src;     */
                    189:        mov.b   @REG_SRC,r0
                    190:        mov.b   r0,@-REG_DST
                    191:        add     #-1,REG_LEN
                    192: 1:
                    193:
                    194:
                    195:        mov     #1,r0
                    196:        cmp/hi  r0,REG_LEN      /* if ( (len > 1) &&       */
                    197:        bf/s    1f
                    198:        mov     REG_SRC,r0
                    199:        tst     #2,r0           /*      (src & 2) {        */
                    200:        bt      1f
                    201:        add     #-2,REG_SRC     /*        *--((unsigned short*)dst) = *--((unsigned short*)src); */
                    202:        mov.w   @REG_SRC,r0
                    203:        add     #-2,REG_LEN     /*        len -= 2;                                              */
                    204:        mov.w   r0,@-REG_DST    /* }                       */
                    205: 1:
                    206:
                    207:
                    208:        mov     #3,r1
                    209:        cmp/hi  r1,REG_LEN      /* while ( len > 3 ) {     */
                    210:        bf/s    ov_no_align_delay
                    211:        tst     REG_LEN,REG_LEN
                    212: 2:
                    213:        add     #-4,REG_SRC
                    214:        mov.l   @REG_SRC,r0     /*   *((unsigned long*)dst)++ = *((unsigned long*)src)++;        */
                    215:        add     #-4,REG_LEN     /*   len -= 4;                                                   */
                    216:        cmp/hi  r1,REG_LEN
                    217:        bt/s    2b
                    218:        mov.l   r0,@-REG_DST    /* }                       */
                    219:
                    220:        bra     ov_no_align_delay
                    221:        tst     REG_LEN,REG_LEN
                    222:
                    223:
                    224: ov_word_align:
                    225:        mov     r1,r0
                    226:        tst     #1,r0
                    227:        bf/s    ov_no_align_delay
                    228:        tst     REG_LEN,REG_LEN /* if ( len == 0 ) return; */
                    229:        bt      bcopy_return
                    230:
                    231:
                    232:        mov     REG_SRC,r0      /* if ( src & 1 )          */
                    233:        tst     #1,r0
                    234:        bt      1f
                    235:        add     #-1,REG_SRC
                    236:        mov.b   @REG_SRC,r0     /*    *--dst = *--src;     */
                    237:        add     #-1,REG_LEN
                    238:        mov.b   r0,@-REG_DST
                    239: 1:
                    240:
                    241:
                    242:        mov     #1,r1
                    243:        cmp/hi  r1,REG_LEN      /* while ( len > 1 ) {     */
                    244:        bf/s    ov_no_align_delay
                    245:        tst     REG_LEN,REG_LEN
                    246: 2:
                    247:        add     #-2,REG_SRC
                    248:        mov.w   @REG_SRC,r0     /*   *--((unsigned short*)dst) = *--((unsigned short*)src);      */
                    249:        add     #-2,REG_LEN     /*   len -= 2;                                                   */
                    250:        cmp/hi  r1,REG_LEN
                    251:        bt/s    2b
                    252:        mov.w   r0,@-REG_DST    /* }                       */
                    253:
                    254:
                    255: ov_no_align:
                    256:        tst     REG_LEN,REG_LEN /* while ( len!= ) {       */
                    257: ov_no_align_delay:
                    258:        bt      9f
                    259: 1:
                    260:        add     #-1,REG_SRC
                    261:        mov.b   @REG_SRC,r0     /*    *--dst = *--src;     */
                    262:        add     #-1,REG_LEN     /*    len--;               */
                    263:        tst     REG_LEN,REG_LEN
                    264:        bf/s    1b
                    265:        mov.b   r0,@-REG_DST    /* }                       */
                    266: 9:
                    267:        rts
                    268: #ifdef REG_DST0
                    269:        mov     REG_DST0,r0
                    270: #else
                    271:        nop
                    272: #endif

CVSweb