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