|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.