Annotation of XNU/osfmk/ppc/bzero.s, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22:  /*
        !            23:  * @OSF_FREE_COPYRIGHT@
        !            24:  */
        !            25: 
        !            26: #include <ppc/asm.h>
        !            27: #include <ppc/proc_reg.h>      /* For CACHE_LINE_SIZE */
        !            28: 
        !            29: /*
        !            30:  *      void   bzero(char *addr, unsigned int length)
        !            31:  *
        !            32:  * bzero implementation for PowerPC
        !            33:  *   - assumes cacheable memory (i.e. uses DCBZ)
        !            34:  *   - assumes non-pic code
        !            35:  *
        !            36:  * returns start address in r3, as per memset (called by memset)
        !            37:  */    
        !            38:        
        !            39: ENTRY(bzero, TAG_NO_FRAME_USED)
        !            40: 
        !            41:        cmpwi   cr0,    r4,     0 /* no bytes to zero? */
        !            42:        mr      r7,     r3
        !            43:        mr      r8,     r3      /* use r8 as counter to where we are */
        !            44:        beqlr-
        !            45:        cmpwi   cr0,    r4,     CACHE_LINE_SIZE /* clear less than a block? */
        !            46:        li      r0,     0        /* use r0 as source of zeros */
        !            47:        blt     .L_bzeroEndWord
        !            48: 
        !            49: /* first, clear bytes up to the next word boundary */
        !            50:        addis   r6,     0,      HIGH_CADDR(.L_bzeroBeginWord)
        !            51:        addi    r6,     r6,     LOW_ADDR(.L_bzeroBeginWord)
        !            52:                 /* extract byte offset as word offset */
        !            53:        rlwinm. r5,     r8,     2,      28,     29
        !            54:        addi    r8,     r8,     -1 /* adjust for update */
        !            55:        beq     .L_bzeroBeginWord /* no bytes to zero */
        !            56:        subfic  r5,     r5,     16 /* compute the number of instructions */
        !            57:        sub     r6,     r6,     r5 /* back from word clear to execute */
        !            58:        mtctr   r6
        !            59:        bctr
        !            60: 
        !            61:        stbu    r0,     1(r8)
        !            62:        stbu    r0,     1(r8)
        !            63:        stbu    r0,     1(r8)
        !            64: 
        !            65: /* clear words up to the next block boundary */
        !            66: .L_bzeroBeginWord:
        !            67:        addis   r6,     0,      HIGH_CADDR(.L_bzeroBlock)
        !            68:        addi    r6,     r6,     LOW_ADDR(.L_bzeroBlock)
        !            69:        addi    r8,     r8,     1
        !            70:        rlwinm. r5,     r8,     0,      27,     29 /* extract word offset */
        !            71:        addi    r8,     r8,     -4              /* adjust for update */
        !            72:        beq     .L_bzeroBlock                   /* no words to zero */
        !            73:                /* compute the number of instructions */
        !            74:        subfic  r5,     r5,     CACHE_LINE_SIZE
        !            75:        sub     r6,     r6,     r5 /* back from word clear to execute */
        !            76:        mtctr   r6
        !            77:        bctr
        !            78: 
        !            79:        stwu    r0,     4(r8)
        !            80:        stwu    r0,     4(r8)
        !            81:        stwu    r0,     4(r8)
        !            82:        stwu    r0,     4(r8)
        !            83:        stwu    r0,     4(r8)
        !            84:        stwu    r0,     4(r8)
        !            85:        stwu    r0,     4(r8)
        !            86: 
        !            87:  /* clear cache blocks */
        !            88: .L_bzeroBlock:
        !            89:        addi    r8,     r8,     4 /* remove update adjust */
        !            90:        sub     r5,     r8,     r7 /* bytes zeroed */
        !            91:        sub     r4,     r4,     r5
        !            92:        srwi.   r5,     r4,     CACHE_LINE_POW2 /* blocks to zero */
        !            93:        beq     .L_bzeroEndWord
        !            94:        mtctr   r5
        !            95: 
        !            96: .L_bzeroBlock1:
        !            97:        dcbz    0,      r8
        !            98:        addi    r8,     r8,     CACHE_LINE_SIZE
        !            99:        bdnz    .L_bzeroBlock1
        !           100: 
        !           101:  /* clear remaining words */
        !           102: .L_bzeroEndWord:
        !           103:        addis   r6,     0,      HIGH_CADDR(.L_bzeroEndByte)
        !           104:        addi    r6,     r6,     LOW_ADDR(.L_bzeroEndByte)
        !           105:        rlwinm. r5,     r4,     0,      27,     29 /* extract word offset */
        !           106:        addi    r8,     r8,     -4                 /* adjust for update */
        !           107:        beq     .L_bzeroEndByte                    /* no words to zero */
        !           108:        sub     r6,     r6,     r5 /* back from word clear to execute */
        !           109:        mtctr   r6
        !           110:        bctr
        !           111: 
        !           112:        stwu    r0,     4(r8)
        !           113:        stwu    r0,     4(r8)
        !           114:        stwu    r0,     4(r8)
        !           115:        stwu    r0,     4(r8)
        !           116:        stwu    r0,     4(r8)
        !           117:        stwu    r0,     4(r8)
        !           118:        stwu    r0,     4(r8)
        !           119: 
        !           120:  /* clear remaining bytes */
        !           121: .L_bzeroEndByte:
        !           122:        addis   r6,     0,      HIGH_CADDR(.L_bzeroEnd)
        !           123:        addi    r6,     r6,     LOW_ADDR(.L_bzeroEnd)
        !           124:                /* extract byte offset as word offset */
        !           125:        rlwinm. r5,     r4,     2,      28,     29
        !           126:        addi    r8,     r8,     3 /* adjust for update */
        !           127:        beqlr
        !           128:        sub     r6,     r6,     r5 /* back from word clear to execute */
        !           129:        mtctr   r6
        !           130:        bctr
        !           131: 
        !           132:        stbu    r0,     1(r8)
        !           133:        stbu    r0,     1(r8)
        !           134:        stbu    r0,     1(r8)
        !           135: 
        !           136: .L_bzeroEnd:
        !           137:        blr
        !           138: 
        !           139: /*
        !           140:  * void *memset(void *from, int c, vm_size_t nbytes)
        !           141:  *
        !           142:  * almost everywhere in the kernel 
        !           143:  * this appears to be called with argument c==0. We optimise for those 
        !           144:  * cases and call bzero if we can.
        !           145:  *
        !           146:  */
        !           147: 
        !           148: ENTRY(memset, TAG_NO_FRAME_USED)
        !           149: 
        !           150:        mr.     ARG3,   ARG1
        !           151:        mr      ARG1,   ARG2
        !           152:        /* optimised case - do a bzero */
        !           153:        beq+    EXT(bzero)
        !           154: 
        !           155:        /* If count is zero, return straight away */
        !           156:        cmpi    cr0,    ARG1,   0
        !           157:        beqlr-  
        !           158:        
        !           159:        /* Now, ARG0 = addr, ARG1=len, ARG3=value */
        !           160: 
        !           161:        subi    ARG2,   ARG0,   1       /* use ARG2 as our counter */
        !           162:        
        !           163: 0:
        !           164:        subi    ARG1,   ARG1,   1
        !           165:        cmpi    cr0,    ARG1,   0
        !           166:        stbu    ARG3,   1(ARG2)
        !           167:        bne+    0b
        !           168: 
        !           169:        /* Return original address in ARG0 */
        !           170:        
        !           171:        blr

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.