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 .global memset 10*e3f2b1a9SAlexei Fedorov 11*e3f2b1a9SAlexei Fedorov/* ----------------------------------------------------------------------- 12*e3f2b1a9SAlexei Fedorov * void *memset(void *dst, int val, size_t count) 13*e3f2b1a9SAlexei Fedorov * 14*e3f2b1a9SAlexei Fedorov * Copy the value of 'val' (converted to an unsigned char) into 15*e3f2b1a9SAlexei Fedorov * each of the first 'count' characters of the object pointed to by 'dst'. 16*e3f2b1a9SAlexei Fedorov * 17*e3f2b1a9SAlexei Fedorov * Returns the value of 'dst'. 18*e3f2b1a9SAlexei Fedorov * ----------------------------------------------------------------------- 19*e3f2b1a9SAlexei Fedorov */ 20*e3f2b1a9SAlexei Fedorovfunc memset 21*e3f2b1a9SAlexei Fedorov cbz x2, exit /* exit if 'count' = 0 */ 22*e3f2b1a9SAlexei Fedorov mov x3, x0 /* keep x0 */ 23*e3f2b1a9SAlexei Fedorov tst x0, #7 24*e3f2b1a9SAlexei Fedorov b.eq aligned /* 8-bytes aligned */ 25*e3f2b1a9SAlexei Fedorov 26*e3f2b1a9SAlexei Fedorov /* Unaligned 'dst' */ 27*e3f2b1a9SAlexei Fedorovunaligned: 28*e3f2b1a9SAlexei Fedorov strb w1, [x3], #1 29*e3f2b1a9SAlexei Fedorov subs x2, x2, #1 30*e3f2b1a9SAlexei Fedorov b.eq exit /* exit if 0 */ 31*e3f2b1a9SAlexei Fedorov tst x3, #7 32*e3f2b1a9SAlexei Fedorov b.ne unaligned /* continue while unaligned */ 33*e3f2b1a9SAlexei Fedorov 34*e3f2b1a9SAlexei Fedorov /* 8-bytes aligned */ 35*e3f2b1a9SAlexei Fedorovaligned:cbz x1, x1_zero 36*e3f2b1a9SAlexei Fedorov bfi w1, w1, #8, #8 /* propagate 'val' */ 37*e3f2b1a9SAlexei Fedorov bfi w1, w1, #16, #16 38*e3f2b1a9SAlexei Fedorov bfi x1, x1, #32, #32 39*e3f2b1a9SAlexei Fedorov 40*e3f2b1a9SAlexei Fedorovx1_zero:ands x4, x2, #~0x3f 41*e3f2b1a9SAlexei Fedorov b.eq less_64 42*e3f2b1a9SAlexei Fedorov 43*e3f2b1a9SAlexei Fedorovwrite_64: 44*e3f2b1a9SAlexei Fedorov .rept 4 45*e3f2b1a9SAlexei Fedorov stp x1, x1, [x3], #16 /* write 64 bytes in a loop */ 46*e3f2b1a9SAlexei Fedorov .endr 47*e3f2b1a9SAlexei Fedorov subs x4, x4, #64 48*e3f2b1a9SAlexei Fedorov b.ne write_64 49*e3f2b1a9SAlexei Fedorovless_64:tbz w2, #5, less_32 /* < 32 bytes */ 50*e3f2b1a9SAlexei Fedorov stp x1, x1, [x3], #16 /* write 32 bytes */ 51*e3f2b1a9SAlexei Fedorov stp x1, x1, [x3], #16 52*e3f2b1a9SAlexei Fedorovless_32:tbz w2, #4, less_16 /* < 16 bytes */ 53*e3f2b1a9SAlexei Fedorov stp x1, x1, [x3], #16 /* write 16 bytes */ 54*e3f2b1a9SAlexei Fedorovless_16:tbz w2, #3, less_8 /* < 8 bytes */ 55*e3f2b1a9SAlexei Fedorov str x1, [x3], #8 /* write 8 bytes */ 56*e3f2b1a9SAlexei Fedorovless_8: tbz w2, #2, less_4 /* < 4 bytes */ 57*e3f2b1a9SAlexei Fedorov str w1, [x3], #4 /* write 4 bytes */ 58*e3f2b1a9SAlexei Fedorovless_4: tbz w2, #1, less_2 /* < 2 bytes */ 59*e3f2b1a9SAlexei Fedorov strh w1, [x3], #2 /* write 2 bytes */ 60*e3f2b1a9SAlexei Fedorovless_2: tbz w2, #0, exit 61*e3f2b1a9SAlexei Fedorov strb w1, [x3] /* write 1 byte */ 62*e3f2b1a9SAlexei Fedorovexit: ret 63*e3f2b1a9SAlexei Fedorov 64*e3f2b1a9SAlexei Fedorovendfunc memset 65