1 /* string.h: Efficient string functions in sparc-assembly for 2 the linux kernel. 3
4 Copyright 1994 (c) David S. Miller (davem@caip.rutgers.edu) 5 */ 6
7
8 /* If we are smart we will use only the output and global registers 9 as that will allow us to avoid a window save which would be nice. 10 */ 11
12 /* Believe it or not the following strlen is not optimized enough! 13 In the future I may play games with doing word reads and reducing 14 the per-word comparisons to *one*, yes I have seen it done. 15 */ 16 .align 4
17 .globl _strlen
18 _strlen:
19 mov %o0, %g3 ! leaf-procedure optimization, here
20 ldsb [%g3], %g2 ! I only use the register sent to me
21 cmp %g2, 0 ! and the globals. Now, this routine
22 be 1f ! is callable from boot code.
23 nop
24 add %o0, 1, %o0
25 0: ldsb [%o0], %g2
26 cmp %g2, 0
27 bne,a 0b ! annulling branch, yuck
28 add %o0, 1, %o0
29
30 1: retl
31 sub %o0, %g3, %o0 ! since %g3 holds the original pointer
32 ! and %o0 is at the end byte, we can
33 ! subtract and the result is strlen.
34
35 /* String concatenate function. I am too lazy to honor the third count 36 argument at this time. Once again, this could be optimized so much 37 more to use word accesses instead of slooow byte loads. 38 */ 39 .align 4
40 .globl _strcat
41 _strcat:
42 mov %o0, %g4
43 ldsb [%g4], %g3
44 cmp %g3, 0
45 be,a 2f
46 ldub [%o1], %g3
47 add %o0, 1, %o0
48
49 0: ldsb [%o0], %g3
50 cmp %g3, 0
51 bne,a 0b
52 add %o0, 1, %o0
53
54 1: ldub [%o1], %g3
55
56 2: add %o1, 1, %o1
57 stb %g3, [%o0]
58 cmp %g3, 0
59 bne 1b
60 add %o0, 1, %o0
61 retl
62 mov %g4, %o0
63
64 /* Aieee, this code is starting to give me a headache. I shouldn't 65 have tried to do this in one sitting :-( 66 */ 67
68 .align 4
69 .globl _strcmp
70 _strcmp: b 2f
71 ldsb [%o1], %g4
72
73 0: sll %o2, 24, %g3
74 cmp %g3, 0
75 bne 1f
76 add %o0, 1, %o0
77 b 3f
78 or %g0, %g0, %o0
79
80 1: ldsb [%o1], %g4
81
82 2: ldsb [%o0], %g3
83 add %o1, 1, %o1
84 cmp %g3, %g4
85 be 0b
86 mov %g3, %o2
87 ldub [%o2], %g3
88 ldub [%o1-1], %o0 ! oh man, no joke
89 sub %g2, %o0, %o0
90
91 3: retl
92 nop
93
94 /* Ok, strcpy() should be easy enough. Maybe I catch some sleep after 95 this one.... 96 */ 97 .align 4
98 .globl _strcpy
99 _strcpy: ldub [%o1], %g3
100 mov %o0, %g4
101 cmp %g3, 0
102 be 1f
103 stb %g3, [%g4]
104
105 0: add %o1, 1, %o1
106 ldub [%o1], %g3
107 add %o0, 1, %o0
108 cmp %g3, 0
109 bne 0b
110 stb %g3, [%o0]
111
112 1: retl
113 mov %g4, %o0
114
115