xref: /freebsd/lib/libc/powerpc64/string/strcpy_arch_2_05.S (revision 1d386b48a555f61cb7325543adbbb5c3f3407a66)
1075fb85fSLeandro Lupori/*-
2075fb85fSLeandro Lupori * Copyright (c) 2018 Instituto de Pesquisas Eldorado
3075fb85fSLeandro Lupori * All rights reserved.
4075fb85fSLeandro Lupori *
5075fb85fSLeandro Lupori * Redistribution and use in source and binary forms, with or without
6075fb85fSLeandro Lupori * modification, are permitted provided that the following conditions
7075fb85fSLeandro Lupori * are met:
8075fb85fSLeandro Lupori * 1. Redistributions of source code must retain the above copyright
9075fb85fSLeandro Lupori *    notice, this list of conditions and the following disclaimer.
10075fb85fSLeandro Lupori * 2. Redistributions in binary form must reproduce the above copyright
11075fb85fSLeandro Lupori *    notice, this list of conditions and the following disclaimer in the
12075fb85fSLeandro Lupori *    documentation and/or other materials provided with the distribution.
13075fb85fSLeandro Lupori * 3. Neither the name of the author nor the names of its contributors may
14075fb85fSLeandro Lupori *    be used to endorse or promote products derived from this software
15075fb85fSLeandro Lupori *
16075fb85fSLeandro Lupori * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17075fb85fSLeandro Lupori * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18075fb85fSLeandro Lupori * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19075fb85fSLeandro Lupori * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20075fb85fSLeandro Lupori * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21075fb85fSLeandro Lupori * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22075fb85fSLeandro Lupori * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23075fb85fSLeandro Lupori * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24075fb85fSLeandro Lupori * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25075fb85fSLeandro Lupori * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26075fb85fSLeandro Lupori * SUCH DAMAGE.
27075fb85fSLeandro Lupori */
28075fb85fSLeandro Lupori
29075fb85fSLeandro Lupori
30075fb85fSLeandro Lupori#include <machine/asm.h>
31075fb85fSLeandro Lupori#if 0
32075fb85fSLeandro Lupori	RCSID("$NetBSD: strcpy.S,v 1.0 2018/05/08 13:00:49 lbianc Exp $")
33075fb85fSLeandro Lupori#endif
34075fb85fSLeandro Lupori
35075fb85fSLeandro LuporiENTRY(__strcpy_arch_2_05)
36075fb85fSLeandro Lupori	mr	%r8, %r3
37075fb85fSLeandro Lupori
38075fb85fSLeandro Lupori/*
39075fb85fSLeandro Lupori * Aligning the reading address, even if it is already aligned to avoid
40075fb85fSLeandro Lupori * performance degradation with strings with 8 bytes or less.
41075fb85fSLeandro Lupori */
42075fb85fSLeandro Lupori.Lalignment:
43075fb85fSLeandro Lupori	lbz	%r0,0(%r4)
44075fb85fSLeandro Lupori	cmpdi	cr7,%r0,0
45075fb85fSLeandro Lupori	stb	%r0,0(%r8)
46075fb85fSLeandro Lupori	beq	cr7,.Lexit
47075fb85fSLeandro Lupori	addi	%r4,%r4,1
48075fb85fSLeandro Lupori	addi	%r8,%r8,1
49075fb85fSLeandro Lupori	andi.	%r0,%r4,0x7
50075fb85fSLeandro Lupori	bne	.Lalignment
51075fb85fSLeandro Lupori
52075fb85fSLeandro Lupori/* Copy by double word with aligned address. */
53075fb85fSLeandro Lupori.Lcopy_dw:
54075fb85fSLeandro Lupori	ld	%r0,0(%r4)
55075fb85fSLeandro Lupori	xor	%r6,%r6,%r6
56075fb85fSLeandro Lupori	cmpb	%r5,%r0,%r6
57075fb85fSLeandro Lupori	cmpdi	cr7,%r5,0
58075fb85fSLeandro Lupori	bne	cr7,.Lcheck_zero
59075fb85fSLeandro Lupori	/* Backward r8 to use stdu instruction in Lcopy_dw_loop */
60075fb85fSLeandro Lupori	addi	%r8,%r8,-8
61075fb85fSLeandro Lupori.Lcopy_dw_loop:
62075fb85fSLeandro Lupori	stdu	%r0,8(%r8)
63075fb85fSLeandro Lupori	ldu	%r0,8(%r4)
64075fb85fSLeandro Lupori	cmpb	%r5,%r0,%r6
65075fb85fSLeandro Lupori	cmpdi	cr7,%r5,0
66075fb85fSLeandro Lupori	beq	cr7,.Lcopy_dw_loop
67075fb85fSLeandro Lupori
68075fb85fSLeandro Lupori	addi	%r8,%r8,8   /* Forward r8 to use std instruction. */
69*9f50aa45SLeandro Lupori#if defined(__BIG_ENDIAN__)
70075fb85fSLeandro Lupori/* Find where the zero is located. */
71075fb85fSLeandro Lupori.Lcheck_zero:
72075fb85fSLeandro Lupori	rldicr.	%r5,%r0,0,7
73075fb85fSLeandro Lupori	beq	.Lfound_on_byte_0
74075fb85fSLeandro Lupori	rldicr.	%r7,%r0,8,7
75075fb85fSLeandro Lupori	beq	.Lfound_on_byte_1
76075fb85fSLeandro Lupori	rldicr.	%r7,%r0,16,7
77075fb85fSLeandro Lupori	beq	.Lfound_on_byte_2
78075fb85fSLeandro Lupori	rldicr.	%r7,%r0,24,7
79075fb85fSLeandro Lupori	beq	.Lfound_on_byte_3
80075fb85fSLeandro Lupori	andis.	%r7,%r0,0xff00
81075fb85fSLeandro Lupori	beq	.Lfound_on_byte_4
82075fb85fSLeandro Lupori	andis.	%r7,%r0,0xff
83075fb85fSLeandro Lupori	beq	.Lfound_on_byte_5
84075fb85fSLeandro Lupori	andi.	%r7,%r0,0xff00
85075fb85fSLeandro Lupori	beq	.Lfound_on_byte_6
86075fb85fSLeandro Lupori
87075fb85fSLeandro Lupori/* Copy the last string bytes according to the string end position. */
88075fb85fSLeandro Lupori.Lfound_on_byte_7:
89075fb85fSLeandro Lupori	std	%r0,0(%r8)
90075fb85fSLeandro Lupori	b	.Lexit
91075fb85fSLeandro Lupori
92075fb85fSLeandro Lupori.Lfound_on_byte_6:
93075fb85fSLeandro Lupori	srdi	%r6,%r0,32
94075fb85fSLeandro Lupori	stw	%r6,0(%r8)
95075fb85fSLeandro Lupori	srdi	%r6,%r0,16
96075fb85fSLeandro Lupori	sth	%r6,4(%r8)
97075fb85fSLeandro Lupori	srdi	%r6,%r0,8
98075fb85fSLeandro Lupori	stb	%r6,6(%r8)
99075fb85fSLeandro Lupori	b	.Lexit
100075fb85fSLeandro Lupori
101075fb85fSLeandro Lupori.Lfound_on_byte_5:
102075fb85fSLeandro Lupori	srdi	%r6,%r0,32
103075fb85fSLeandro Lupori	stw	%r6,0(%r8)
104075fb85fSLeandro Lupori	srdi	%r6,%r0,16
105075fb85fSLeandro Lupori	sth	%r6,4(%r8)
106075fb85fSLeandro Lupori	b	.Lexit
107075fb85fSLeandro Lupori
108075fb85fSLeandro Lupori.Lfound_on_byte_4:
109075fb85fSLeandro Lupori	srdi	%r6,%r0,32
110075fb85fSLeandro Lupori	stw	%r6,0(%r8)
111075fb85fSLeandro Lupori	srdi	%r6,%r0,24
112075fb85fSLeandro Lupori	stb	%r6,4(%r8)
113075fb85fSLeandro Lupori	b	.Lexit
114075fb85fSLeandro Lupori
115075fb85fSLeandro Lupori.Lfound_on_byte_3:
116075fb85fSLeandro Lupori	srdi	%r6,%r0,32
117075fb85fSLeandro Lupori	stw	%r6,0(%r8)
118075fb85fSLeandro Lupori	b	.Lexit
119075fb85fSLeandro Lupori
120075fb85fSLeandro Lupori.Lfound_on_byte_2:
121075fb85fSLeandro Lupori	srdi	%r6,%r0,48
122075fb85fSLeandro Lupori	sth	%r6,0(%r8)
123075fb85fSLeandro Lupori	srdi	%r6,%r0,40
124075fb85fSLeandro Lupori	stb	%r6,2(%r8)
125075fb85fSLeandro Lupori	b	.Lexit
126075fb85fSLeandro Lupori
127075fb85fSLeandro Lupori.Lfound_on_byte_1:
128075fb85fSLeandro Lupori	srdi	%r6,%r0,48
129075fb85fSLeandro Lupori	sth	%r6,0(%r8)
130075fb85fSLeandro Lupori	b	.Lexit
131075fb85fSLeandro Lupori
132075fb85fSLeandro Lupori.Lfound_on_byte_0:
133075fb85fSLeandro Lupori	srdi	%r6,%r0,56
134075fb85fSLeandro Lupori	stb	%r6,0(%r8)
135*9f50aa45SLeandro Lupori#elif defined(__LITTLE_ENDIAN__)
136*9f50aa45SLeandro Lupori/* Find where the zero is located. */
137*9f50aa45SLeandro Lupori.Lcheck_zero:
138*9f50aa45SLeandro Lupori	andi.	%r7,%r0,0xff
139*9f50aa45SLeandro Lupori	beq	.Lfound_on_byte_0
140*9f50aa45SLeandro Lupori	andi.	%r7,%r0,0xff00
141*9f50aa45SLeandro Lupori	beq	.Lfound_on_byte_1
142*9f50aa45SLeandro Lupori	andis.	%r7,%r0,0xff
143*9f50aa45SLeandro Lupori	beq	.Lfound_on_byte_2
144*9f50aa45SLeandro Lupori	andis.	%r7,%r0,0xff00
145*9f50aa45SLeandro Lupori	beq	.Lfound_on_byte_3
146*9f50aa45SLeandro Lupori	rldicr.	%r7,%r0,24,7
147*9f50aa45SLeandro Lupori	beq	.Lfound_on_byte_4
148*9f50aa45SLeandro Lupori	rldicr.	%r7,%r0,16,7
149*9f50aa45SLeandro Lupori	beq	.Lfound_on_byte_5
150*9f50aa45SLeandro Lupori	rldicr.	%r7,%r0,8,7
151*9f50aa45SLeandro Lupori	beq	.Lfound_on_byte_6
152*9f50aa45SLeandro Lupori
153*9f50aa45SLeandro Lupori/* Copy the last string bytes according to the string end position. */
154*9f50aa45SLeandro Lupori.Lfound_on_byte_7:
155*9f50aa45SLeandro Lupori	std	%r0,0(%r8)
156*9f50aa45SLeandro Lupori	b	.Lexit
157*9f50aa45SLeandro Lupori
158*9f50aa45SLeandro Lupori.Lfound_on_byte_6:
159*9f50aa45SLeandro Lupori	stw	%r0,0(%r8)
160*9f50aa45SLeandro Lupori	srdi	%r6,%r0,32
161*9f50aa45SLeandro Lupori	sth	%r6,4(%r8)
162*9f50aa45SLeandro Lupori	srdi	%r6,%r0,48
163*9f50aa45SLeandro Lupori	stb	%r6,6(%r8)
164*9f50aa45SLeandro Lupori	b	.Lexit
165*9f50aa45SLeandro Lupori
166*9f50aa45SLeandro Lupori.Lfound_on_byte_5:
167*9f50aa45SLeandro Lupori	stw	%r0,0(%r8)
168*9f50aa45SLeandro Lupori	srdi	%r6,%r0,32
169*9f50aa45SLeandro Lupori	sth	%r6,4(%r8)
170*9f50aa45SLeandro Lupori	b	.Lexit
171*9f50aa45SLeandro Lupori
172*9f50aa45SLeandro Lupori.Lfound_on_byte_4:
173*9f50aa45SLeandro Lupori	stw	%r0,0(%r8)
174*9f50aa45SLeandro Lupori	srdi	%r6,%r0,32
175*9f50aa45SLeandro Lupori	stb	%r6,4(%r8)
176*9f50aa45SLeandro Lupori	b	.Lexit
177*9f50aa45SLeandro Lupori
178*9f50aa45SLeandro Lupori.Lfound_on_byte_3:
179*9f50aa45SLeandro Lupori	stw	%r0,0(%r8)
180*9f50aa45SLeandro Lupori	b	.Lexit
181*9f50aa45SLeandro Lupori
182*9f50aa45SLeandro Lupori.Lfound_on_byte_2:
183*9f50aa45SLeandro Lupori	sth	%r0,0(%r8)
184*9f50aa45SLeandro Lupori	srdi	%r6,%r0,16
185*9f50aa45SLeandro Lupori	stb	%r6,2(%r8)
186*9f50aa45SLeandro Lupori	b	.Lexit
187*9f50aa45SLeandro Lupori
188*9f50aa45SLeandro Lupori.Lfound_on_byte_1:
189*9f50aa45SLeandro Lupori	sth	%r0,0(%r8)
190*9f50aa45SLeandro Lupori	b	.Lexit
191*9f50aa45SLeandro Lupori
192*9f50aa45SLeandro Lupori.Lfound_on_byte_0:
193*9f50aa45SLeandro Lupori	stb	%r0,0(%r8)
194*9f50aa45SLeandro Lupori#else
195*9f50aa45SLeandro Lupori#error "Unable to determine Endianness"
196*9f50aa45SLeandro Lupori#endif
197075fb85fSLeandro Lupori.Lexit:
198075fb85fSLeandro Lupori	blr
199075fb85fSLeandro Lupori
200075fb85fSLeandro LuporiEND(__strcpy_arch_2_05)
201075fb85fSLeandro Lupori
202075fb85fSLeandro Lupori	.section .note.GNU-stack,"",%progbits
203