xref: /freebsd/lib/libc/powerpc64/string/memcpy.S (revision 1d386b48a555f61cb7325543adbbb5c3f3407a66)
1e16c1865SLeandro Lupori/*-
2e16c1865SLeandro Lupori * Copyright (c) 2018 Instituto de Pesquisas Eldorado
3e16c1865SLeandro Lupori * All rights reserved.
4e16c1865SLeandro Lupori *
5e16c1865SLeandro Lupori * Redistribution and use in source and binary forms, with or without
6e16c1865SLeandro Lupori * modification, are permitted provided that the following conditions
7e16c1865SLeandro Lupori * are met:
8e16c1865SLeandro Lupori * 1. Redistributions of source code must retain the above copyright
9e16c1865SLeandro Lupori *    notice, this list of conditions and the following disclaimer.
10e16c1865SLeandro Lupori * 2. Redistributions in binary form must reproduce the above copyright
11e16c1865SLeandro Lupori *    notice, this list of conditions and the following disclaimer in the
12e16c1865SLeandro Lupori *    documentation and/or other materials provided with the distribution.
13e16c1865SLeandro Lupori * 3. Neither the name of the author nor the names of its contributors may
14e16c1865SLeandro Lupori *    be used to endorse or promote products derived from this software
15e16c1865SLeandro Lupori *
16e16c1865SLeandro Lupori * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17e16c1865SLeandro Lupori * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18e16c1865SLeandro Lupori * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19e16c1865SLeandro Lupori * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20e16c1865SLeandro Lupori * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21e16c1865SLeandro Lupori * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22e16c1865SLeandro Lupori * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23e16c1865SLeandro Lupori * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24e16c1865SLeandro Lupori * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25e16c1865SLeandro Lupori * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26e16c1865SLeandro Lupori * SUCH DAMAGE.
27e16c1865SLeandro Lupori *
28e16c1865SLeandro Lupori */
29e16c1865SLeandro Lupori
30e16c1865SLeandro Lupori#include <machine/asm.h>
31e16c1865SLeandro Lupori#ifndef FN_NAME
32e16c1865SLeandro Lupori#define FN_NAME				__memcpy
33e16c1865SLeandro LuporiWEAK_REFERENCE(__memcpy, memcpy);
34e16c1865SLeandro Lupori#define BLOCK_BITS			4
35e16c1865SLeandro Lupori#endif
36e16c1865SLeandro Lupori
37e16c1865SLeandro Lupori#define BLOCK_BYTES			(1 << BLOCK_BITS)
38e16c1865SLeandro Lupori#define BLOCK_MASK			(BLOCK_BYTES - 1)
39e16c1865SLeandro Lupori
4000797360SJustin Hibbits/* Minimum 8 byte alignment, to avoid cache-inhibited alignment faults. */
4100797360SJustin Hibbits#ifndef ALIGN_MASK
4200797360SJustin Hibbits#define	ALIGN_MASK			0x7
4300797360SJustin Hibbits#endif
4400797360SJustin Hibbits
45e16c1865SLeandro Lupori/*
46e16c1865SLeandro Lupori * r3: dst
47e16c1865SLeandro Lupori * r4: src
48e16c1865SLeandro Lupori * r5: len
49e16c1865SLeandro Lupori */
50e16c1865SLeandro LuporiENTRY(FN_NAME)
51e16c1865SLeandro Lupori	cmpdi	%r5, 0			/* len == 0? nothing to do */
52e16c1865SLeandro Lupori	beqlr-
53e16c1865SLeandro Lupori
5400797360SJustin Hibbits	/* If src and dst are relatively misaligned, do byte copies. */
5500797360SJustin Hibbits	andi.	%r8, %r3, ALIGN_MASK
5600797360SJustin Hibbits	andi.	%r7, %r4, ALIGN_MASK
5700797360SJustin Hibbits	cmpd	%r8, %r7
5800797360SJustin Hibbits	mr	%r7, %r5
59e16c1865SLeandro Lupori	mr	%r8, %r3		/* save dst */
60*db7f521dSBrandon Bergren	bne	.Lcopy_remaining_fix_index_byte
61e16c1865SLeandro Lupori
62e16c1865SLeandro Lupori	/* align src */
63e16c1865SLeandro Lupori.Lalignment_loop:
64e16c1865SLeandro Lupori	lbz	%r6, 0(%r4)
65e16c1865SLeandro Lupori	stb	%r6, 0(%r3)
66e16c1865SLeandro Lupori	addi	%r3, %r3, 1
67e16c1865SLeandro Lupori	addi	%r4, %r4, 1
68e16c1865SLeandro Lupori	addi	%r5, %r5, -1
69e16c1865SLeandro Lupori	cmpdi	%r5, 0
70e16c1865SLeandro Lupori	beq	.Lexit
71e16c1865SLeandro Lupori	andi.	%r0, %r4, BLOCK_MASK
72e16c1865SLeandro Lupori	bne	.Lalignment_loop
73e16c1865SLeandro Lupori
74e16c1865SLeandro Lupori	/* r7 = remaining, non-block, bytes */
75e16c1865SLeandro Lupori	andi.	%r7, %r5, BLOCK_MASK
76e16c1865SLeandro Lupori
77e16c1865SLeandro Lupori	/* Check if there are blocks of BLOCK_BYTES to be copied */
78e16c1865SLeandro Lupori	xor.	%r5, %r5, %r7
79e16c1865SLeandro Lupori	beq	.Lcopy_remaining_fix_index_byte
80e16c1865SLeandro Lupori
81e16c1865SLeandro Lupori#ifdef FN_COPY_LOOP
82e16c1865SLeandro LuporiFN_COPY_LOOP
83e16c1865SLeandro Lupori#else
84e16c1865SLeandro Lupori	/* Setup to copy word with ldu and stdu */
85e16c1865SLeandro Lupori	ld	%r6, 0(%r4)
86e16c1865SLeandro Lupori	ld	%r9, 8(%r4)
87e16c1865SLeandro Lupori	std	%r6, 0(%r3)
88e16c1865SLeandro Lupori	std	%r9, 8(%r3)
89e16c1865SLeandro Lupori	addi	%r5, %r5, -BLOCK_BYTES
90e16c1865SLeandro Lupori	cmpd	%r5, 0
91e16c1865SLeandro Lupori	beq	.Lcopy_remaining_fix_index_word
92e16c1865SLeandro Lupori
93e16c1865SLeandro Lupori	srdi	%r5, %r5, BLOCK_BITS
94e16c1865SLeandro Lupori	mtctr	%r5
95e16c1865SLeandro Lupori.Lcopy_word:
96e16c1865SLeandro Lupori	ldu	%r6, 16(%r4)
97e16c1865SLeandro Lupori	ld	%r9,  8(%r4)
98e16c1865SLeandro Lupori	stdu	%r6, 16(%r3)
99e16c1865SLeandro Lupori	std	%r9,  8(%r3)
100e16c1865SLeandro Lupori	bdnz	.Lcopy_word
101e16c1865SLeandro Lupori
102e16c1865SLeandro Lupori.Lcopy_remaining_fix_index_word:
103e16c1865SLeandro Lupori	/* Check if there are remaining bytes */
104e16c1865SLeandro Lupori	cmpd	%r7, 0
105e16c1865SLeandro Lupori	beq	.Lexit
106e16c1865SLeandro Lupori	addi	%r3, %r3, BLOCK_MASK
107e16c1865SLeandro Lupori	addi	%r4, %r4, BLOCK_MASK
108e16c1865SLeandro Lupori	b	.Lcopy_remaining
109e16c1865SLeandro Lupori#endif
110e16c1865SLeandro Lupori
111e16c1865SLeandro Lupori.Lcopy_remaining_fix_index_byte:
112e16c1865SLeandro Lupori	addi	%r4, %r4, -1
113e16c1865SLeandro Lupori	addi	%r3, %r3, -1
114e16c1865SLeandro Lupori
115e16c1865SLeandro Lupori	/* Copy remaining bytes */
116e16c1865SLeandro Lupori.Lcopy_remaining:
117e16c1865SLeandro Lupori	mtctr	%r7
118e16c1865SLeandro Lupori.Lcopy_remaining_loop:
119e16c1865SLeandro Lupori	lbzu	%r6, 1(%r4)
120e16c1865SLeandro Lupori	stbu	%r6, 1(%r3)
121e16c1865SLeandro Lupori	bdnz	.Lcopy_remaining_loop
122e16c1865SLeandro Lupori
123e16c1865SLeandro Lupori.Lexit:
124e16c1865SLeandro Lupori	/* Restore dst */
125e16c1865SLeandro Lupori	mr	%r3, %r8
126e16c1865SLeandro Lupori	blr
127e16c1865SLeandro Lupori
128e16c1865SLeandro LuporiEND(FN_NAME)
129e16c1865SLeandro Lupori
130e16c1865SLeandro Lupori	.section .note.GNU-stack,"",%progbits
131e16c1865SLeandro Lupori
132