xref: /openbsd/lib/libc/arch/powerpc/string/memmove.S (revision 0be5e928)
1*0be5e928Sguenther/* $OpenBSD: memmove.S,v 1.5 2022/06/10 01:56:02 guenther Exp $ */
2f75309e9Sderaadt/* $NetBSD: memmove.S,v 1.3 2011/01/15 07:31:12 matt Exp $ */
3f75309e9Sderaadt
4f75309e9Sderaadt/* stropt/memmove.S, pl_string_common, pl_linux 10/11/04 11:45:37
5f75309e9Sderaadt * ==========================================================================
6f75309e9Sderaadt * Optimized memmove implementation for IBM PowerPC 405/440.
7f75309e9Sderaadt *
8f75309e9Sderaadt *	Copyright (c) 2003, IBM Corporation
9f75309e9Sderaadt *	All rights reserved.
10f75309e9Sderaadt *
11f75309e9Sderaadt *	Redistribution and use in source and binary forms, with or
12f75309e9Sderaadt *	without modification, are permitted provided that the following
13f75309e9Sderaadt *	conditions are met:
14f75309e9Sderaadt *
15f75309e9Sderaadt *	* Redistributions of source code must retain the above
16f75309e9Sderaadt *	copyright notice, this list of conditions and the following
17f75309e9Sderaadt *	disclaimer.
18f75309e9Sderaadt *	* Redistributions in binary form must reproduce the above
19f75309e9Sderaadt *	copyright notice, this list of conditions and the following
20f75309e9Sderaadt *	disclaimer in the documentation and/or other materials
21f75309e9Sderaadt *	provided with the distribution.
22f75309e9Sderaadt *	* Neither the name of IBM nor the names of its contributors
23f75309e9Sderaadt *	may be used to endorse or promote products derived from this
24f75309e9Sderaadt *	software without specific prior written permission.
25f75309e9Sderaadt *
26f75309e9Sderaadt *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
27f75309e9Sderaadt *	CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
28f75309e9Sderaadt *	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29f75309e9Sderaadt *	MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30f75309e9Sderaadt *	DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
31f75309e9Sderaadt *	BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
32f75309e9Sderaadt *	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33f75309e9Sderaadt *	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34f75309e9Sderaadt *	PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
35f75309e9Sderaadt *	OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36f75309e9Sderaadt *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37f75309e9Sderaadt *	USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38f75309e9Sderaadt *
39f75309e9Sderaadt * ==========================================================================
40f75309e9Sderaadt */
41f75309e9Sderaadt
42*0be5e928Sguenther#include "DEFS.h"
43f75309e9Sderaadt
44f75309e9Sderaadt        .text
45f75309e9Sderaadt
46f75309e9Sderaadt/* void *memcpy(void *to, const void *from, size_t len) */
47d2c5a474Sgkoehler#if 0
48d2c5a474SgkoehlerENTRY(memcpy)
4915572fcfSgkoehler	RETGUARD_SETUP(memmove, %r11, %r12)
50f75309e9Sderaadt	mr	%r8, %r3		/* Save dst (return value)	*/
51*0be5e928Sguenther	b	.Lfwd
52d2c5a474Sgkoehler#endif
53f75309e9Sderaadt
54f75309e9Sderaadt/* void bcopy(void *, void *, size_t) */
55*0be5e928SguentherENTRY_NB(bcopy)
56f75309e9Sderaadt	mr	%r6, %r3		/* swap src/dst */
57f75309e9Sderaadt	mr	%r3, %r4
58f75309e9Sderaadt	mr	%r4, %r6
59f75309e9Sderaadt
60f75309e9Sderaadt/* void *memmove(void *, const void *, size_t) */
61f75309e9SderaadtENTRY(memmove)
6215572fcfSgkoehler	RETGUARD_SETUP(memmove, %r11, %r12)
63f75309e9Sderaadt	mr	%r8, %r3		/* Save dst (return value)	*/
64f75309e9Sderaadt
65f75309e9Sderaadt	cmpw	%r4, %r8		/* Branch to reverse if 	*/
66*0be5e928Sguenther	blt	.Lreverse		/* src < dest. Don't want to	*/
67f75309e9Sderaadt					/* overwrite end of src with	*/
68f75309e9Sderaadt					/* start of dest 		*/
69f75309e9Sderaadt
70*0be5e928Sguenther.Lfwd:
71f75309e9Sderaadt	addi	%r4, %r4, -4		/* Back up src and dst pointers */
72f75309e9Sderaadt	addi	%r8, %r8, -4		/* due to auto-update of 'load' */
73f75309e9Sderaadt
74f75309e9Sderaadt	srwi.	%r9,%r5,2		/* How many words in total cnt	*/
75*0be5e928Sguenther	beq-	.Llast1			/* Handle byte by byte if < 4	*/
76f75309e9Sderaadt					/* bytes total 			*/
77f75309e9Sderaadt	mtctr	%r9			/* Count of words for loop	*/
78f75309e9Sderaadt	lwzu	%r7, 4(%r4)		/* Preload first word		*/
79f75309e9Sderaadt
80*0be5e928Sguenther	b	.Lg1
81f75309e9Sderaadt
82*0be5e928Sguenther.Lg0:					/* Main loop			*/
83f75309e9Sderaadt
84f75309e9Sderaadt	lwzu	%r7, 4(%r4)		/* Load a new word		*/
85f75309e9Sderaadt	stwu	%r6, 4(%r8)		/* Store previous word		*/
86f75309e9Sderaadt
87*0be5e928Sguenther.Lg1:
88f75309e9Sderaadt
89*0be5e928Sguenther	bdz-	.Llast			/* Dec cnt, and branch if just	*/
90f75309e9Sderaadt					/* one word to store		*/
91f75309e9Sderaadt	lwzu	%r6, 4(%r4)		/* Load another word		*/
92f75309e9Sderaadt	stwu	%r7, 4(%r8)		/* Store previous word		*/
93*0be5e928Sguenther	bdnz+	.Lg0			/* Dec cnt, and loop again if	*/
94f75309e9Sderaadt					/* more words			*/
95f75309e9Sderaadt	mr	%r7, %r6		/* If word count -> 0, then...	*/
96f75309e9Sderaadt
97*0be5e928Sguenther.Llast:
98f75309e9Sderaadt
99f75309e9Sderaadt	stwu	%r7, 4(%r8)		/* ... store last word		*/
100f75309e9Sderaadt
101*0be5e928Sguenther.Llast1:				/* Byte-by-byte copy		*/
102f75309e9Sderaadt
103f75309e9Sderaadt	clrlwi.	%r5,%r5,30		/* If count -> 0, then ...	*/
104*0be5e928Sguenther	beq	.Ldone			/* we're done			*/
105f75309e9Sderaadt
106f75309e9Sderaadt	mtctr	%r5			/* else load count for loop	*/
107f75309e9Sderaadt
108f75309e9Sderaadt	lbzu	%r6, 4(%r4)		/* 1st byte: update addr by 4	*/
109f75309e9Sderaadt	stbu	%r6, 4(%r8)		/* since we pre-adjusted by 4	*/
110*0be5e928Sguenther	bdz-	.Ldone			/* in anticipation of main loop */
111f75309e9Sderaadt
112*0be5e928Sguenther.Llast2:
113f75309e9Sderaadt
114f75309e9Sderaadt	lbzu	%r6, 1(%r4)		/* But handle the rest by	*/
115f75309e9Sderaadt	stbu	%r6, 1(%r8)		/* updating addr by 1		*/
116*0be5e928Sguenther	bdnz+	.Llast2
117*0be5e928Sguenther	b	.Ldone
118f75309e9Sderaadt
119f75309e9Sderaadt	/* We're here since src < dest. Don't want to overwrite end of	*/
120f75309e9Sderaadt	/* src with start of dest					*/
121f75309e9Sderaadt
122*0be5e928Sguenther.Lreverse:
123f75309e9Sderaadt
124f75309e9Sderaadt	add	%r4, %r4, %r5		/* Work from end to beginning	*/
125f75309e9Sderaadt	add	%r8, %r8, %r5 		/* so add count to string ptrs	*/
126f75309e9Sderaadt	srwi.	%r9,%r5,2		/* Words in total count		*/
127*0be5e928Sguenther	beq-	.Lrlast1		/* Handle byte by byte if < 4	*/
128f75309e9Sderaadt					/* bytes total 			*/
129f75309e9Sderaadt
130f75309e9Sderaadt	mtctr	%r9			/* Count of words for loop 	*/
131f75309e9Sderaadt
132f75309e9Sderaadt	lwzu	%r7, -4(%r4)		/* Preload first word		*/
133*0be5e928Sguenther	b	.Lrg1
134f75309e9Sderaadt
135*0be5e928Sguenther.Lrg0:					/* Main loop			*/
136f75309e9Sderaadt
137f75309e9Sderaadt	lwzu	%r7, -4(%r4)		/* Load a new word		*/
138f75309e9Sderaadt	stwu	%r6, -4(%r8)		/* Store previous word		*/
139f75309e9Sderaadt
140*0be5e928Sguenther.Lrg1:
141f75309e9Sderaadt
142*0be5e928Sguenther	bdz-	.Lrlast			/* Dec cnt, and branch if just	*/
143f75309e9Sderaadt					/* one word to store		*/
144f75309e9Sderaadt
145f75309e9Sderaadt	lwzu	%r6, -4(%r4)		/* Load another word		*/
146f75309e9Sderaadt	stwu	%r7, -4(%r8)		/* Store previous word		*/
147f75309e9Sderaadt
148*0be5e928Sguenther	bdnz+	.Lrg0			/* Dec cnt, and loop again if	*/
149f75309e9Sderaadt					/* more words			*/
150f75309e9Sderaadt
151f75309e9Sderaadt	mr	%r7, %r6		/* If word count -> 0, then...	*/
152f75309e9Sderaadt
153*0be5e928Sguenther.Lrlast:
154f75309e9Sderaadt
155f75309e9Sderaadt	stwu	%r7, -4(%r8)		/* ... store last word		*/
156f75309e9Sderaadt
157*0be5e928Sguenther.Lrlast1:				/* Byte-by-byte copy		*/
158f75309e9Sderaadt
159f75309e9Sderaadt	clrlwi.	%r5,%r5,30		/* If count -> 0, then...	*/
160*0be5e928Sguenther	beq	.Ldone			/* ... we're done 		*/
161f75309e9Sderaadt
162f75309e9Sderaadt	mtctr	%r5			/* else load count for loop 	*/
163f75309e9Sderaadt
164*0be5e928Sguenther.Lrlast2:
165f75309e9Sderaadt
166f75309e9Sderaadt	lbzu	%r6, -1(%r4)		/* Handle the rest, byte by 	*/
167f75309e9Sderaadt	stbu	%r6, -1(%r8)		/* byte				*/
168f75309e9Sderaadt
169*0be5e928Sguenther	bdnz+	.Lrlast2	 	/* Dec ctr, and branch if more	*/
170f75309e9Sderaadt					/* bytes left			*/
171*0be5e928Sguenther.Ldone:
17215572fcfSgkoehler	RETGUARD_CHECK(memmove, %r11, %r12)
173f75309e9Sderaadt	blr
1749b9d2a55SguentherEND_STRONG(memmove)
1759b9d2a55SguentherEND_WEAK(bcopy)
176