xref: /freebsd/lib/libc/powerpc64/string/strncpy_arch_2_05.S (revision 1d386b48a555f61cb7325543adbbb5c3f3407a66)
1*181e3500SLeandro Lupori/*-
2*181e3500SLeandro Lupori * Copyright (c) 2018 Instituto de Pesquisas Eldorado
3*181e3500SLeandro Lupori * All rights reserved.
4*181e3500SLeandro Lupori *
5*181e3500SLeandro Lupori * Redistribution and use in source and binary forms, with or without
6*181e3500SLeandro Lupori * modification, are permitted provided that the following conditions
7*181e3500SLeandro Lupori * are met:
8*181e3500SLeandro Lupori * 1. Redistributions of source code must retain the above copyright
9*181e3500SLeandro Lupori *    notice, this list of conditions and the following disclaimer.
10*181e3500SLeandro Lupori * 2. Redistributions in binary form must reproduce the above copyright
11*181e3500SLeandro Lupori *    notice, this list of conditions and the following disclaimer in the
12*181e3500SLeandro Lupori *    documentation and/or other materials provided with the distribution.
13*181e3500SLeandro Lupori * 3. Neither the name of the author nor the names of its contributors may
14*181e3500SLeandro Lupori *    be used to endorse or promote products derived from this software
15*181e3500SLeandro Lupori *
16*181e3500SLeandro Lupori * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*181e3500SLeandro Lupori * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*181e3500SLeandro Lupori * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*181e3500SLeandro Lupori * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*181e3500SLeandro Lupori * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*181e3500SLeandro Lupori * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*181e3500SLeandro Lupori * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*181e3500SLeandro Lupori * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*181e3500SLeandro Lupori * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*181e3500SLeandro Lupori * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*181e3500SLeandro Lupori * SUCH DAMAGE.
27*181e3500SLeandro Lupori */
28*181e3500SLeandro Lupori
29*181e3500SLeandro Lupori#include <machine/asm.h>
30*181e3500SLeandro LuporiENTRY(__strncpy_arch_2_05)
31*181e3500SLeandro Lupori	stdu	%r1,-40(%r1)
32*181e3500SLeandro Lupori	mflr	%r0
33*181e3500SLeandro Lupori	std	%r0,16(%r1)
34*181e3500SLeandro Lupori	std	%r3,32(%r1)
35*181e3500SLeandro Lupori
36*181e3500SLeandro Lupori	xor	%r6,%r6,%r6	/* fixed 0 reg */
37*181e3500SLeandro Lupori
38*181e3500SLeandro Lupori/* align loop */
39*181e3500SLeandro Lupori	addi	%r3,%r3,-1
40*181e3500SLeandro Lupori.Lalign_loop:
41*181e3500SLeandro Lupori	/* len? */
42*181e3500SLeandro Lupori	cmpdi	%r5,0
43*181e3500SLeandro Lupori	beq	.Lexit
44*181e3500SLeandro Lupori	/* aligned? */
45*181e3500SLeandro Lupori	andi.	%r0,%r4,7
46*181e3500SLeandro Lupori	beq	.Ldw_copy
47*181e3500SLeandro Lupori	/* copy */
48*181e3500SLeandro Lupori	lbz	%r7,0(%r4)
49*181e3500SLeandro Lupori	stbu	%r7,1(%r3)
50*181e3500SLeandro Lupori	addi	%r4,%r4,1
51*181e3500SLeandro Lupori	addi	%r5,%r5,-1
52*181e3500SLeandro Lupori	/* zero? */
53*181e3500SLeandro Lupori	cmpdi	%r7,0
54*181e3500SLeandro Lupori	beq	.Lzero
55*181e3500SLeandro Lupori	b	.Lalign_loop
56*181e3500SLeandro Lupori
57*181e3500SLeandro Lupori/* dword copy loop */
58*181e3500SLeandro Lupori.Ldw_copy:
59*181e3500SLeandro Lupori	/* prepare src and dst to use load/store and update */
60*181e3500SLeandro Lupori	addi	%r3,%r3,-7
61*181e3500SLeandro Lupori	addi	%r4,%r4,-8
62*181e3500SLeandro Lupori.Ldw_copy_loop:
63*181e3500SLeandro Lupori	cmpdi	%r5,8
64*181e3500SLeandro Lupori	blt	.Lbyte_copy
65*181e3500SLeandro Lupori
66*181e3500SLeandro Lupori	ldu	%r0,8(%r4)
67*181e3500SLeandro Lupori	/* check for 0 */
68*181e3500SLeandro Lupori	cmpb	%r7,%r0,%r6
69*181e3500SLeandro Lupori	cmpdi	%r7,0
70*181e3500SLeandro Lupori	bne	.Lbyte_copy_and_zero
71*181e3500SLeandro Lupori	/* copy to dst */
72*181e3500SLeandro Lupori	stdu	%r0,8(%r3)
73*181e3500SLeandro Lupori	addi	%r5,%r5,-8
74*181e3500SLeandro Lupori	b	.Ldw_copy_loop
75*181e3500SLeandro Lupori
76*181e3500SLeandro Lupori/* Copy remaining src bytes, zero-out buffer
77*181e3500SLeandro Lupori * Note: r5 will be >= 8
78*181e3500SLeandro Lupori */
79*181e3500SLeandro Lupori.Lbyte_copy_and_zero:
80*181e3500SLeandro Lupori	addi	%r3,%r3,7
81*181e3500SLeandro Lupori	addi	%r4,%r4,-1
82*181e3500SLeandro Lupori.Lbyte_copy_and_zero_loop:
83*181e3500SLeandro Lupori	lbzu	%r7,1(%r4)
84*181e3500SLeandro Lupori	stbu	%r7,1(%r3)
85*181e3500SLeandro Lupori	addi	%r5,%r5,-1
86*181e3500SLeandro Lupori	cmpdi	%r7,0
87*181e3500SLeandro Lupori	beq	.Lzero
88*181e3500SLeandro Lupori	b	.Lbyte_copy_and_zero_loop
89*181e3500SLeandro Lupori
90*181e3500SLeandro Lupori/* zero-out remaining dst bytes */
91*181e3500SLeandro Lupori.Lzero:
92*181e3500SLeandro Lupori	addi	%r3,%r3,1
93*181e3500SLeandro Lupori	li	%r4,0
94*181e3500SLeandro Lupori	/* r5 has len already */
95*181e3500SLeandro Lupori	bl	memset
96*181e3500SLeandro Lupori	nop
97*181e3500SLeandro Lupori	b	.Lexit
98*181e3500SLeandro Lupori
99*181e3500SLeandro Lupori/* copy remaining (< 8) bytes */
100*181e3500SLeandro Lupori.Lbyte_copy:
101*181e3500SLeandro Lupori	cmpdi	%r5,0
102*181e3500SLeandro Lupori	beq	.Lexit
103*181e3500SLeandro Lupori	addi	%r3,%r3,7
104*181e3500SLeandro Lupori	addi	%r4,%r4,7
105*181e3500SLeandro Lupori	mtctr	%r5
106*181e3500SLeandro Lupori.Lbyte_copy_loop:
107*181e3500SLeandro Lupori	lbzu	%r7,1(%r4)
108*181e3500SLeandro Lupori	stbu	%r7,1(%r3)
109*181e3500SLeandro Lupori	cmpdi	%r7,0
110*181e3500SLeandro Lupori	/* 0 found: zero out remaining bytes */
111*181e3500SLeandro Lupori	beq	.Lbyte_copy_zero
112*181e3500SLeandro Lupori	bdnz	.Lbyte_copy_loop
113*181e3500SLeandro Lupori	b	.Lexit
114*181e3500SLeandro Lupori.Lbyte_copy_zero_loop:
115*181e3500SLeandro Lupori	stbu	%r6,1(%r3)
116*181e3500SLeandro Lupori.Lbyte_copy_zero:
117*181e3500SLeandro Lupori	bdnz	.Lbyte_copy_zero_loop
118*181e3500SLeandro Lupori
119*181e3500SLeandro Lupori.Lexit:
120*181e3500SLeandro Lupori	/* epilogue */
121*181e3500SLeandro Lupori	ld	%r3,32(%r1)
122*181e3500SLeandro Lupori	ld	%r0,16(%r1)
123*181e3500SLeandro Lupori	mtlr	%r0
124*181e3500SLeandro Lupori	addi	%r1,%r1,40
125*181e3500SLeandro Lupori	blr
126*181e3500SLeandro Lupori
127*181e3500SLeandro LuporiEND(__strncpy_arch_2_05)
128*181e3500SLeandro Lupori
129*181e3500SLeandro Lupori	.section .note.GNU-stack,"",%progbits
130