4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
31 / Concatenates s2 on the end of s1. s1
's space must be large enough.
32 / At most n characters are moved.
35 / Fast assembly language version of the following C-program strncat
36 / which represents the `standard' for the C-library.
39 / strncat
(char
*s1
, const char
*s2
, size_t n
)
47 / while
(*s1+
+ = *s2+
+)
55 / In this assembly language version
, the following expression is used
56 / to check if
a 32-bit word data contains
a null byte
or not:
57 / (((A & 0x7f7f7f7f) + 0x7f7f7f7f) |
A) & 0x80808080
58 / If the above expression geneates
a value other than
0x80808080,
59 / that means the
32-bit word data contains
a null byte.
65 pushl
%edi
/ save register variables
67 movl
12(%esp
), %edi
/ %edi
= destination string address
68 testl $
3, %edi
/ if
%edi
not word aligned
72 movl
(%edi
), %edx
/ move
1 word from
(%edi
) to
%edx
73 movl $
0x7f7f7f7f, %ecx
74 andl
%edx
, %ecx
/ %ecx
= %edx
& 0x7f7f7f7f
75 addl $
4, %edi
/ next word
76 addl $
0x7f7f7f7f, %ecx
/ %ecx
+= 0x7f7f7f7f
77 orl
%edx
, %ecx
/ %ecx |
= %edx
78 andl $
0x80808080, %ecx
/ %ecx
&= 0x80808080
79 cmpl $
0x80808080, %ecx
/ if no null byte in this word
81 subl $
4, %edi
/ post-incremented
83 cmpb $
0, (%edi
) / if
a byte in
(%edi
) is null
86 testl $
3, %edi
/ if
%edi
not word aligned
88 jmp
.L2 / goto .L2 (%edi word aligned)
91 / %edi points to
a null byte in destination string
92 movl
16(%esp
), %eax
/ %eax
= source string address
93 movl
20(%esp
), %esi
/ %esi
= number of bytes
95 testl $
3, %eax
/ if
%eax
not word aligned
97 cmpl $
4, %esi
/ if number of bytes
< 4
101 movl
(%eax
), %edx
/ move
1 word from
(%eax
) to
%edx
102 movl $
0x7f7f7f7f, %ecx
103 andl
%edx
, %ecx
/ %ecx
= %edx
& 0x7f7f7f7f
104 addl $
4, %eax
/ next word
105 addl $
0x7f7f7f7f, %ecx
/ %ecx
+= 0x7f7f7f7f
106 orl
%edx
, %ecx
/ %ecx |
= %edx
107 andl $
0x80808080, %ecx
/ %ecx
&= 0x80808080
108 cmpl $
0x80808080, %ecx
/ if null byte in this word
110 movl
%edx
, (%edi
) / copy this word to
(%edi
)
111 subl $
4, %esi
/ decrement number of bytes by
4
112 addl $
4, %edi
/ next word
113 cmpl $
4, %esi
/ if number of bytes
>= 4
117 subl $
4, %eax
/ post-incremented
120 / number of bytes
< 4 or a null byte found in the word
121 cmpl $
0, %esi
/ if number of bytes
== 0
122 jz
.L8 / goto .L8 (finished)
123 movb
(%eax
), %dl
/ %dl
= a byte in
(%eax
)
124 decl
%esi
/ decrement number of bytes by
1
125 movb
%dl
, (%edi
) / copy
%dl to
(%edi
)
126 incl
%eax
/ next byte
127 incl
%edi
/ next byte
128 cmpb $
0, %dl
/ compare
%dl with
a null byte
129 je
.L9 / if %dl is a null, goto .L9
135 cmpl $
0, %esi
/ if number of bytes
== 0
136 jz
.L8 / goto .L8 (finished)
137 movb
(%eax
), %dl
/ %dl
= a byte in
(%eax
)
138 decl
%esi
/ decrement number of bytes by
1
139 movb
%dl
, (%edi
) / copy
%dl to
(%edi
)
140 incl
%edi
/ next byte
141 incl
%eax
/ next byte
142 cmpb $
0, %dl
/ compare
%dl with
a null byte
143 je
.L9 / if %dl is a null, goto .L9
147 movb $
0, (%edi
) / null termination
149 movl
12(%esp
), %eax
/ return the destination address
150 popl
%esi
/ restore register variables