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