Annotation of XNU/bsd/dev/ppc/xsumas.s, revision 1.1.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: #define STANDALONE 0
                     23: 
                     24: #if STANDALONE
                     25: #include "asm.h"
                     26: #include "assym.h"
                     27: #include "proc_reg.h"  /* For CACHE_LINE_SIZE */
                     28:     
                     29: #else
                     30:     
                     31: #include <mach/ppc/asm.h>
                     32: #if 0
                     33: /* #include <assym.h> */
                     34: #include <ppc/proc_reg.h>      /* For CACHE_LINE_SIZE */
                     35: #endif 0
                     36: #endif
                     37: 
                     38: /*
                     39:  * Reg 3 - Pointer to data
                     40:  * Reg 4 - Length of data
                     41:  * Reg 5 - Accumulated sum value
                     42:  * Reg 6 - Starting on odd boundary flag (relative to byte 0 of the checksumed data)
                     43:  */    
                     44:         
                     45: ENTRY(xsum_assym, TAG_NO_FRAME_USED)
                     46: 
                     47:     mr     r11, r6             ; Swapped flag
                     48:     addi    r8, 0, 0
                     49:     addi    r10, 0, 0x1f
                     50:     addi    r7, 0, 1
                     51:     addic   r7, r7, 0          ; This clears the carry bit!
                     52:     mr     r12, r5             ; Save the passed-in checksum value
                     53:     
                     54:     /*
                     55:     * Sum bytes before cache line boundary
                     56:     */
                     57: 
                     58:     cmpi    cr0,0,r4,0         ; Check for length of 0
                     59:     beq            Lleftovers
                     60:     
                     61:     and.    r9, r3, r10
                     62:     beq            Laligned32          ; 32 byte aligned
                     63: 
                     64:     andi.   r9, r3, 0x3
                     65:     beq            Laligned4
                     66:     
                     67:     andi.   r9, r3, 0x1
                     68:     beq            Laligned2           ; 2 byte aligned
                     69: 
                     70:     addi    r11, 0, 1          ; swap bytes at end
                     71:     lbz            r8, 0(r3)
                     72:     add     r3, r3, r7
                     73:     subf.   r4, r7, r4
                     74:     beq            Ldone
                     75: 
                     76: Laligned2:
                     77:     cmpi    cr0,0,r4,2         ; If remaining length is less than two - go to wrap-up
                     78:     blt            Lleftovers
                     79:     andi.   r9, r3, 0x3                ; If aligned on a 4-byte boundary, go to that code
                     80:     beq            Laligned4
                     81:     lhz            r5, 0(r3)           ; Load and add a halfword to the checksum
                     82:     adde    r8, r8, r5
                     83:     slwi    r7, r7, 1
                     84:     add     r3, r3, r7
                     85:     subf.   r4, r7, r4
                     86:     beq            Ldone
                     87: 
                     88: 
                     89:     /*
                     90:      Add longwords up to the 32 byte boundary
                     91:     */
                     92:     
                     93: Laligned4:
                     94:     addi    r7, 0, 4   
                     95: Lloop4:        
                     96:     cmpi    cr0,0,r4,4
                     97:     blt            Lleftovers
                     98:     and.    r9, r3, r10
                     99:     beq            Laligned32
                    100:     lwz            r5, 0(r3)
                    101:     adde    r8, r8, r5
                    102:     add     r3, r3, r7
                    103:     subf.   r4, r7, r4
                    104:     bne            Lloop4
                    105:     b      Ldone
                    106: 
                    107: 
                    108:     /*
                    109:     We're aligned on a 32 byte boundary now - add 8 longwords to checksum
                    110:     until the remaining length is less than 32
                    111:     */
                    112: Laligned32:
                    113:     andis.  r6, r4, 0xffff
                    114:     bne            Lmainloop
                    115:     andi.   r6, r4, 0xffe0
                    116:     beq            Lleftovers  
                    117: 
                    118: Lmainloop:             
                    119:     addi    r9, 0, 64
                    120:     addi    r10, 0, 32
                    121:     cmpi    cr0,0,r4,64
                    122:     blt            Lnopretouch
                    123:     dcbt    r3, r10            ; Touch one cache-line ahead 
                    124: Lnopretouch:   
                    125:     lwz            r5, 0(r3)
                    126: 
                    127:     /*
                    128:     * This is the main meat of the checksum. I attempted to arrange this code
                    129:     * such that the processor would execute as many instructions as possible
                    130:     * in parallel.
                    131:     */
                    132: 
                    133: Lloop:
                    134:     cmpi    cr0,0,r4,96
                    135:     blt            Lnotouch    
                    136:     dcbt    r3, r9             ; Touch two cache lines ahead 
                    137: Lnotouch:   
                    138:     adde    r8, r8, r5
                    139:     lwz     r5, 4(r3)
                    140:     lwz            r6, 8(r3)
                    141:     lwz            r7, 12(r3)
                    142:     adde    r8, r8, r5
                    143:     lwz     r5, 16(r3)
                    144:     adde    r8, r8, r6
                    145:     lwz            r6, 20(r3)
                    146:     adde    r8, r8, r7
                    147:     lwz            r7, 24(r3)
                    148:     adde    r8, r8, r5
                    149:     lwz            r5, 28(r3)
                    150:     add     r3, r3, r10
                    151:     adde    r8, r8, r6
                    152:     adde    r8, r8, r7
                    153:     adde    r8, r8, r5
                    154:     subf    r4, r10, r4
                    155:     andi.   r6, r4, 0xffe0
                    156:     beq            Lleftovers
                    157:     lwz            r5, 0(r3)
                    158:     b      Lloop
                    159: 
                    160:     /*
                    161:     * Handle whatever bytes are left
                    162:     */
                    163:     
                    164: Lleftovers: 
                    165:     /*
                    166:     * Handle leftover bytes
                    167:     */
                    168:     cmpi    cr0,0,r4,0
                    169:     beq            Ldone
                    170:     
                    171:     addi    r7, 0, 1
                    172:     addi    r10, 0, 0x7ffc
                    173: 
                    174:     and.    r9, r4, r10
                    175:     bne            Lfourormore
                    176:     srw            r10, r10, r7
                    177:     and.    r9, r4, r10
                    178:     bne     Ltwoormore
                    179:     b      Loneleft
                    180: 
                    181: Lfourormore:
                    182:     addi    r10, 0, 4
                    183:     
                    184: Lfourloop:  
                    185:     lwz            r5, 0(r3)
                    186:     adde    r8, r8, r5
                    187:     add     r3, r3, r10
                    188:     subf    r4, r10, r4   
                    189:     andi.   r6, r4, 0xfffc
                    190:     bne            Lfourloop
                    191: 
                    192: Ltwoormore: 
                    193:     andi.   r6, r4, 0xfffe
                    194:     beq            Loneleft
                    195:     lhz            r5, 0(r3)
                    196:     adde    r8, r8, r5
                    197:     addi    r3, r3, 2
                    198:     subi    r4, r4, 2
                    199: 
                    200: Loneleft:   
                    201:     cmpi    cr0,0,r4,0
                    202:     beq            Ldone
                    203:     lbz            r5, 0(r3)
                    204:     slwi    r5, r5, 8
                    205:     adde    r8, r8, r5
                    206: 
                    207:     /*
                    208:     * Wrap the longword around, adding the two 16-bit portions
                    209:     * to each other along with any previous and subsequent carries.
                    210:     */
                    211: Ldone:
                    212:     addze   r8, r8             ; Add the carry 
                    213:     addze   r8, r8             ; Add the carry again (the last add may have carried) 
                    214:     andis.  r6, r8, 0xffff     ; Stuff r6 with the high order 16 bits of  sum word
                    215:     srwi    r6, r6, 16         ; Shift it to the low order word
                    216:     andi.   r8, r8, 0xffff     ; Zero out the high order word
                    217:     add     r8, r8, r6         ; Add the two halves
                    218: 
                    219:     andis.  r6, r8, 0xffff     ; Do the above again in case we carried into the
                    220:     srwi    r6, r6, 16         ; high order word with the last add.
                    221:     andi.   r8, r8, 0xffff
                    222:     add     r3, r8, r6
                    223: 
                    224:     cmpi    cr0,0,r11,0                ; Check to see if we need to swap the bytes
                    225:     beq            Ldontswap
                    226: 
                    227:     /*
                    228:     * Our buffer began on an odd boundary, so we need to swap
                    229:     * the checksum bytes.
                    230:     */
                    231:     slwi    r8,        r3, 8           ; shift byte 0 to byte 1
                    232:     clrlwi  r8, r8, 16         ; Clear top 16 bits
                    233:     srwi    r3, r3, 8          ; shift byte 1 to byte 0
                    234:     or     r3, r8, r3          ; or them
                    235: 
                    236: Ldontswap:
                    237:     add     r3, r3, r12                ; Add in the passed-in checksum
                    238:     andis.  r6, r3, 0xffff     ; Wrap and add any carries into the top 16 bits
                    239:     srwi    r6, r6, 16
                    240:     andi.   r3, r3, 0xffff
                    241:     add     r3, r3, r6
                    242: 
                    243:     andis.  r6, r3, 0xffff     ; Do the above again in case we carried into the
                    244:     srwi    r6, r6, 16         ; high order word with the last add.
                    245:     andi.   r3, r3, 0xffff
                    246:     add     r3, r3, r6
                    247:     blr
                    248: 
                    249:     

unix.superglobalmegacorp.com

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