|
|
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.