]> git.saurik.com Git - apple/libc.git/blob - gen.subproj/ppc.subproj/strlen.s
baa1216bdb997e9ffd98b54994b5239e66a3e408
[apple/libc.git] / gen.subproj / ppc.subproj / strlen.s
1 /*
2 * Copyright (c) 1999 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 /* Copyright (c) 1992, 1997 NeXT Software, Inc. All rights reserved.
23 *
24 * File: libc/gen/ppc/strlen.s
25 *
26 * HISTORY
27 * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com)
28 * Ported to PPC.
29 * 12-Nov-92 Derek B Clegg (dclegg@next.com)
30 * Created.
31 *
32 * size_t strlen(const char *s);
33 *
34 * Description:
35 *
36 * Returns:
37 */
38 #import <architecture/ppc/asm_help.h>
39 #import <architecture/ppc/pseudo_inst.h>
40
41 /* size_t strlen(const char *s); */
42
43 #define a8 ep
44 #define a9 at
45
46 .at_off
47
48 #define check_for_zero(reg, tmp, found_zero, checked_all) \
49 extrwi. tmp,reg,8,0 @\
50 beq- found_zero @\
51 bdz- checked_all @\
52 extrwi. tmp,reg,8,8 @\
53 beq- found_zero @\
54 bdz- checked_all @\
55 extrwi. tmp,reg,8,16 @\
56 beq- found_zero @\
57 bdz- checked_all @\
58 extrwi. tmp,reg,8,24 @\
59 beq- found_zero @\
60 bdz- checked_all
61
62 #define check_32(tmp, found_zero) \
63 check_for_zero(a2, tmp, found_zero, 1f) @\
64 check_for_zero(a3, tmp, found_zero, 1f) @\
65 check_for_zero(a4, tmp, found_zero, 1f) @\
66 check_for_zero(a5, tmp, found_zero, 1f) @\
67 check_for_zero(a6, tmp, found_zero, 1f) @\
68 check_for_zero(a7, tmp, found_zero, 1f) @\
69 check_for_zero(a8, tmp, found_zero, 1f) @\
70 check_for_zero(a9, tmp, found_zero, 1f) @\
71 1:
72
73 LEAF(_strlen)
74 dcbt 0,a0 // Try to load the cache line.
75 andi. a1,a0,31 // We want to be 32-byte aligned.
76 subfic a1,a1,32 // Get the number of bytes to start with.
77 mtxer a1 // Setup xer for load.
78 lswx a2,0,a0 // Load the bytes.
79 mtctr a1 // Setup ctr for zero check.
80 check_32(zt, L_found_zero)
81
82 /* Now check 32-byte blocks. At this point, ctr is zero, so we can
83 * use it as our running count. */
84 dcbt a1,a0 // Try to load the cache line.
85 li32 a2,32
86 mtxer a2
87 li32 a2,0
88 mtctr a2
89
90 2: lswx a2,a1,a0 // Load 32 bytes.
91 check_32(zt, L_found_zero)
92 addi a0,a0,32 // Increment the pointer.
93 dcbt a1,a0 // Try to load the cache.
94 b 2b // Loop
95
96 L_found_zero:
97 mfctr a0
98 sub a0,a1,a0 // Get the number of bytes before 0.
99 blr // Return.
100 END(_strlen)