131914882SAlex Richardson/*
231914882SAlex Richardson * memset - fill memory with a constant
331914882SAlex Richardson *
431914882SAlex Richardson * Copyright (c) 2010-2021, Arm Limited.
5*072a4ba8SAndrew Turner * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
631914882SAlex Richardson */
731914882SAlex Richardson
831914882SAlex Richardson/*
931914882SAlex Richardson   Written by Dave Gilbert <david.gilbert@linaro.org>
1031914882SAlex Richardson
1131914882SAlex Richardson   This memset routine is optimised on a Cortex-A9 and should work on
1231914882SAlex Richardson   all ARMv7 processors.
1331914882SAlex Richardson
1431914882SAlex Richardson */
1531914882SAlex Richardson
1631914882SAlex Richardson	.syntax unified
1731914882SAlex Richardson	.arch armv7-a
1831914882SAlex Richardson
1931914882SAlex Richardson@ 2011-08-30 david.gilbert@linaro.org
2031914882SAlex Richardson@    Extracted from local git 2f11b436
2131914882SAlex Richardson
2231914882SAlex Richardson@ this lets us check a flag in a 00/ff byte easily in either endianness
2331914882SAlex Richardson#ifdef __ARMEB__
2431914882SAlex Richardson#define CHARTSTMASK(c) 1<<(31-(c*8))
2531914882SAlex Richardson#else
2631914882SAlex Richardson#define CHARTSTMASK(c) 1<<(c*8)
2731914882SAlex Richardson#endif
2831914882SAlex Richardson	.thumb
2931914882SAlex Richardson
3031914882SAlex Richardson@ ---------------------------------------------------------------------------
3131914882SAlex Richardson	.thumb_func
3231914882SAlex Richardson	.align 2
3331914882SAlex Richardson	.p2align 4,,15
3431914882SAlex Richardson	.global __memset_arm
3531914882SAlex Richardson	.type __memset_arm,%function
3631914882SAlex Richardson__memset_arm:
3731914882SAlex Richardson	@ r0 = address
3831914882SAlex Richardson	@ r1 = character
3931914882SAlex Richardson	@ r2 = count
4031914882SAlex Richardson	@ returns original address in r0
4131914882SAlex Richardson
4231914882SAlex Richardson	mov	r3, r0		@ Leave r0 alone
4331914882SAlex Richardson	cbz	r2, 10f		@ Exit if 0 length
4431914882SAlex Richardson
4531914882SAlex Richardson	tst	r0, #7
4631914882SAlex Richardson	beq	2f		@ Already aligned
4731914882SAlex Richardson
4831914882SAlex Richardson	@ Ok, so we're misaligned here
4931914882SAlex Richardson1:
5031914882SAlex Richardson	strb	r1, [r3], #1
5131914882SAlex Richardson	subs	r2,r2,#1
5231914882SAlex Richardson	tst	r3, #7
5331914882SAlex Richardson	cbz	r2, 10f		@ Exit if we hit the end
5431914882SAlex Richardson	bne	1b		@ go round again if still misaligned
5531914882SAlex Richardson
5631914882SAlex Richardson2:
5731914882SAlex Richardson	@ OK, so we're aligned
5831914882SAlex Richardson	push	{r4,r5,r6,r7}
5931914882SAlex Richardson	bics	r4, r2, #15	@ if less than 16 bytes then need to finish it off
6031914882SAlex Richardson	beq	5f
6131914882SAlex Richardson
6231914882SAlex Richardson3:
6331914882SAlex Richardson	@ POSIX says that ch is cast to an unsigned char.  A uxtb is one
6431914882SAlex Richardson	@ byte and takes two cycles, where an AND is four bytes but one
6531914882SAlex Richardson	@ cycle.
6631914882SAlex Richardson	and	r1, #0xFF
6731914882SAlex Richardson	orr	r1, r1, r1, lsl#8	@ Same character into all bytes
6831914882SAlex Richardson	orr	r1, r1, r1, lsl#16
6931914882SAlex Richardson	mov	r5,r1
7031914882SAlex Richardson	mov	r6,r1
7131914882SAlex Richardson	mov	r7,r1
7231914882SAlex Richardson
7331914882SAlex Richardson4:
7431914882SAlex Richardson	subs	r4,r4,#16
7531914882SAlex Richardson	stmia	r3!,{r1,r5,r6,r7}
7631914882SAlex Richardson	bne	4b
7731914882SAlex Richardson	and	r2,r2,#15
7831914882SAlex Richardson
7931914882SAlex Richardson	@ At this point we're still aligned and we have upto align-1 bytes left to right
8031914882SAlex Richardson	@ we can avoid some of the byte-at-a time now by testing for some big chunks
8131914882SAlex Richardson	tst	r2,#8
8231914882SAlex Richardson	itt	ne
8331914882SAlex Richardson	subne	r2,r2,#8
8431914882SAlex Richardson	stmiane	r3!,{r1,r5}
8531914882SAlex Richardson
8631914882SAlex Richardson5:
8731914882SAlex Richardson	pop	{r4,r5,r6,r7}
8831914882SAlex Richardson	cbz	r2, 10f
8931914882SAlex Richardson
9031914882SAlex Richardson	@ Got to do any last < alignment bytes
9131914882SAlex Richardson6:
9231914882SAlex Richardson	subs	r2,r2,#1
9331914882SAlex Richardson	strb	r1,[r3],#1
9431914882SAlex Richardson	bne	6b
9531914882SAlex Richardson
9631914882SAlex Richardson10:
9731914882SAlex Richardson	bx	lr		@ goodbye
9831914882SAlex Richardson	.size	__memset_arm, . - __memset_arm
99