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

Annotation of sys/lib/libkern/arch/sh/memset.S, Revision 1.1

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

CVSweb