Annotation of kernel/machdep/ppc/xsumas.s, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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