1*54fd6939SJiyong Park/* 2*54fd6939SJiyong Park * Copyright (c) 2020, Arm Limited. All rights reserved. 3*54fd6939SJiyong Park * 4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause 5*54fd6939SJiyong Park */ 6*54fd6939SJiyong Park 7*54fd6939SJiyong Park#include <asm_macros.S> 8*54fd6939SJiyong Park 9*54fd6939SJiyong Park .global memset 10*54fd6939SJiyong Park 11*54fd6939SJiyong Park/* ----------------------------------------------------------------------- 12*54fd6939SJiyong Park * void *memset(void *dst, int val, size_t count) 13*54fd6939SJiyong Park * 14*54fd6939SJiyong Park * Copy the value of 'val' (converted to an unsigned char) into 15*54fd6939SJiyong Park * each of the first 'count' characters of the object pointed to by 'dst'. 16*54fd6939SJiyong Park * 17*54fd6939SJiyong Park * Returns the value of 'dst'. 18*54fd6939SJiyong Park * ----------------------------------------------------------------------- 19*54fd6939SJiyong Park */ 20*54fd6939SJiyong Parkfunc memset 21*54fd6939SJiyong Park cbz x2, exit /* exit if 'count' = 0 */ 22*54fd6939SJiyong Park mov x3, x0 /* keep x0 */ 23*54fd6939SJiyong Park tst x0, #7 24*54fd6939SJiyong Park b.eq aligned /* 8-bytes aligned */ 25*54fd6939SJiyong Park 26*54fd6939SJiyong Park /* Unaligned 'dst' */ 27*54fd6939SJiyong Parkunaligned: 28*54fd6939SJiyong Park strb w1, [x3], #1 29*54fd6939SJiyong Park subs x2, x2, #1 30*54fd6939SJiyong Park b.eq exit /* exit if 0 */ 31*54fd6939SJiyong Park tst x3, #7 32*54fd6939SJiyong Park b.ne unaligned /* continue while unaligned */ 33*54fd6939SJiyong Park 34*54fd6939SJiyong Park /* 8-bytes aligned */ 35*54fd6939SJiyong Parkaligned:cbz x1, x1_zero 36*54fd6939SJiyong Park bfi w1, w1, #8, #8 /* propagate 'val' */ 37*54fd6939SJiyong Park bfi w1, w1, #16, #16 38*54fd6939SJiyong Park bfi x1, x1, #32, #32 39*54fd6939SJiyong Park 40*54fd6939SJiyong Parkx1_zero:ands x4, x2, #~0x3f 41*54fd6939SJiyong Park b.eq less_64 42*54fd6939SJiyong Park 43*54fd6939SJiyong Parkwrite_64: 44*54fd6939SJiyong Park .rept 4 45*54fd6939SJiyong Park stp x1, x1, [x3], #16 /* write 64 bytes in a loop */ 46*54fd6939SJiyong Park .endr 47*54fd6939SJiyong Park subs x4, x4, #64 48*54fd6939SJiyong Park b.ne write_64 49*54fd6939SJiyong Parkless_64:tbz w2, #5, less_32 /* < 32 bytes */ 50*54fd6939SJiyong Park stp x1, x1, [x3], #16 /* write 32 bytes */ 51*54fd6939SJiyong Park stp x1, x1, [x3], #16 52*54fd6939SJiyong Parkless_32:tbz w2, #4, less_16 /* < 16 bytes */ 53*54fd6939SJiyong Park stp x1, x1, [x3], #16 /* write 16 bytes */ 54*54fd6939SJiyong Parkless_16:tbz w2, #3, less_8 /* < 8 bytes */ 55*54fd6939SJiyong Park str x1, [x3], #8 /* write 8 bytes */ 56*54fd6939SJiyong Parkless_8: tbz w2, #2, less_4 /* < 4 bytes */ 57*54fd6939SJiyong Park str w1, [x3], #4 /* write 4 bytes */ 58*54fd6939SJiyong Parkless_4: tbz w2, #1, less_2 /* < 2 bytes */ 59*54fd6939SJiyong Park strh w1, [x3], #2 /* write 2 bytes */ 60*54fd6939SJiyong Parkless_2: tbz w2, #0, exit 61*54fd6939SJiyong Park strb w1, [x3] /* write 1 byte */ 62*54fd6939SJiyong Parkexit: ret 63*54fd6939SJiyong Park 64*54fd6939SJiyong Parkendfunc memset 65