xref: /rk3399_ARM-atf/lib/libc/aarch32/memset.S (revision 21023273c9633bc7d8dcc2a0fa11f27a6e9c55b6)
1*e3f2b1a9SAlexei Fedorov/*
2*e3f2b1a9SAlexei Fedorov * Copyright (c) 2020, Arm Limited. All rights reserved.
3*e3f2b1a9SAlexei Fedorov *
4*e3f2b1a9SAlexei Fedorov * SPDX-License-Identifier: BSD-3-Clause
5*e3f2b1a9SAlexei Fedorov */
6*e3f2b1a9SAlexei Fedorov
7*e3f2b1a9SAlexei Fedorov#include <asm_macros.S>
8*e3f2b1a9SAlexei Fedorov
9*e3f2b1a9SAlexei Fedorov	.syntax unified
10*e3f2b1a9SAlexei Fedorov	.global	memset
11*e3f2b1a9SAlexei Fedorov
12*e3f2b1a9SAlexei Fedorov/* -----------------------------------------------------------------------
13*e3f2b1a9SAlexei Fedorov * void *memset(void *dst, int val, size_t count)
14*e3f2b1a9SAlexei Fedorov *
15*e3f2b1a9SAlexei Fedorov * Copy the value of 'val' (converted to an unsigned char) into
16*e3f2b1a9SAlexei Fedorov * each of the first 'count' characters of the object pointed to by 'dst'.
17*e3f2b1a9SAlexei Fedorov *
18*e3f2b1a9SAlexei Fedorov * Returns the value of 'dst'.
19*e3f2b1a9SAlexei Fedorov * -----------------------------------------------------------------------
20*e3f2b1a9SAlexei Fedorov */
21*e3f2b1a9SAlexei Fedorovfunc memset
22*e3f2b1a9SAlexei Fedorov	mov	r12, r0			/* keep r0 */
23*e3f2b1a9SAlexei Fedorov	tst	r0, #3
24*e3f2b1a9SAlexei Fedorov	beq	aligned			/* 4-bytes aligned */
25*e3f2b1a9SAlexei Fedorov
26*e3f2b1a9SAlexei Fedorov	/* Unaligned 'dst' */
27*e3f2b1a9SAlexei Fedorovunaligned:
28*e3f2b1a9SAlexei Fedorov	subs	r2, r2, #1
29*e3f2b1a9SAlexei Fedorov	strbhs	r1, [r12], #1
30*e3f2b1a9SAlexei Fedorov	bxls	lr			/* return if 0 */
31*e3f2b1a9SAlexei Fedorov	tst	r12, #3
32*e3f2b1a9SAlexei Fedorov	bne	unaligned		/* continue while unaligned */
33*e3f2b1a9SAlexei Fedorov
34*e3f2b1a9SAlexei Fedorov	/* 4-bytes aligned */
35*e3f2b1a9SAlexei Fedorovaligned:bfi	r1, r1, #8, #8		/* propagate 'val' */
36*e3f2b1a9SAlexei Fedorov	bfi	r1, r1, #16, #16
37*e3f2b1a9SAlexei Fedorov
38*e3f2b1a9SAlexei Fedorov	mov	r3, r1
39*e3f2b1a9SAlexei Fedorov
40*e3f2b1a9SAlexei Fedorov	cmp	r2, #16
41*e3f2b1a9SAlexei Fedorov	blo	less_16			/* < 16 */
42*e3f2b1a9SAlexei Fedorov
43*e3f2b1a9SAlexei Fedorov	push	{r4, lr}
44*e3f2b1a9SAlexei Fedorov	mov	r4, r1
45*e3f2b1a9SAlexei Fedorov	mov	lr, r1
46*e3f2b1a9SAlexei Fedorov
47*e3f2b1a9SAlexei Fedorovwrite_32:
48*e3f2b1a9SAlexei Fedorov	subs	r2, r2, #32
49*e3f2b1a9SAlexei Fedorov	stmiahs	r12!, {r1, r3, r4, lr}
50*e3f2b1a9SAlexei Fedorov	stmiahs	r12!, {r1, r3, r4, lr}
51*e3f2b1a9SAlexei Fedorov	bhi	write_32		/* write 32 bytes in a loop */
52*e3f2b1a9SAlexei Fedorov	popeq	{r4, pc}		/* return if 0 */
53*e3f2b1a9SAlexei Fedorov	lsls	r2, r2, #28		/* C = r2[4]; N = r2[3]; Z = r2[3:0] */
54*e3f2b1a9SAlexei Fedorov	stmiacs	r12!, {r1, r3, r4, lr}	/* write 16 bytes */
55*e3f2b1a9SAlexei Fedorov	popeq	{r4, pc}		/* return if 16 */
56*e3f2b1a9SAlexei Fedorov	stmiami	r12!, {r1, r3}		/* write 8 bytes */
57*e3f2b1a9SAlexei Fedorov	lsls	r2, r2, #2		/* C = r2[2]; N = r2[1]; Z = r2[1:0] */
58*e3f2b1a9SAlexei Fedorov	strcs	r1, [r12], #4		/* write 4 bytes */
59*e3f2b1a9SAlexei Fedorov	popeq	{r4, pc}		/* return if 8 or 4 */
60*e3f2b1a9SAlexei Fedorov	strhmi	r1, [r12], #2		/* write 2 bytes */
61*e3f2b1a9SAlexei Fedorov	lsls	r2, r2, #1		/* N = Z = r2[0] */
62*e3f2b1a9SAlexei Fedorov	strbmi	r1, [r12]		/* write 1 byte */
63*e3f2b1a9SAlexei Fedorov	pop	{r4, pc}
64*e3f2b1a9SAlexei Fedorov
65*e3f2b1a9SAlexei Fedorovless_16:lsls	r2, r2, #29		/* C = r2[3]; N = r2[2]; Z = r2[2:0] */
66*e3f2b1a9SAlexei Fedorov	stmiacs	r12!, {r1, r3}		/* write 8 bytes */
67*e3f2b1a9SAlexei Fedorov	bxeq	lr			/* return if 8 */
68*e3f2b1a9SAlexei Fedorov	strmi	r1, [r12], #4		/* write 4 bytes */
69*e3f2b1a9SAlexei Fedorov	lsls	r2, r2, #2		/* C = r2[1]; N = Z = r2[0] */
70*e3f2b1a9SAlexei Fedorov	strhcs	r1, [r12], #2		/* write 2 bytes */
71*e3f2b1a9SAlexei Fedorov	strbmi	r1, [r12]		/* write 1 byte */
72*e3f2b1a9SAlexei Fedorov	bx	lr
73*e3f2b1a9SAlexei Fedorov
74*e3f2b1a9SAlexei Fedorovendfunc memset
75