1bbbf1280Sopenharmony_ci/* 2bbbf1280Sopenharmony_ci * memset - fill memory with a constant 3bbbf1280Sopenharmony_ci * 4bbbf1280Sopenharmony_ci * Copyright (c) 2010-2021, Arm Limited. 5bbbf1280Sopenharmony_ci * SPDX-License-Identifier: MIT 6bbbf1280Sopenharmony_ci */ 7bbbf1280Sopenharmony_ci 8bbbf1280Sopenharmony_ci/* 9bbbf1280Sopenharmony_ci Written by Dave Gilbert <david.gilbert@linaro.org> 10bbbf1280Sopenharmony_ci 11bbbf1280Sopenharmony_ci This memset routine is optimised on a Cortex-A9 and should work on 12bbbf1280Sopenharmony_ci all ARMv7 processors. 13bbbf1280Sopenharmony_ci 14bbbf1280Sopenharmony_ci */ 15bbbf1280Sopenharmony_ci 16bbbf1280Sopenharmony_ci .syntax unified 17bbbf1280Sopenharmony_ci .arch armv7-a 18bbbf1280Sopenharmony_ci 19bbbf1280Sopenharmony_ci@ 2011-08-30 david.gilbert@linaro.org 20bbbf1280Sopenharmony_ci@ Extracted from local git 2f11b436 21bbbf1280Sopenharmony_ci 22bbbf1280Sopenharmony_ci@ this lets us check a flag in a 00/ff byte easily in either endianness 23bbbf1280Sopenharmony_ci#ifdef __ARMEB__ 24bbbf1280Sopenharmony_ci#define CHARTSTMASK(c) 1<<(31-(c*8)) 25bbbf1280Sopenharmony_ci#else 26bbbf1280Sopenharmony_ci#define CHARTSTMASK(c) 1<<(c*8) 27bbbf1280Sopenharmony_ci#endif 28bbbf1280Sopenharmony_ci .thumb 29bbbf1280Sopenharmony_ci 30bbbf1280Sopenharmony_ci@ --------------------------------------------------------------------------- 31bbbf1280Sopenharmony_ci .thumb_func 32bbbf1280Sopenharmony_ci .align 2 33bbbf1280Sopenharmony_ci .p2align 4,,15 34bbbf1280Sopenharmony_ci .global __memset_arm 35bbbf1280Sopenharmony_ci .type __memset_arm,%function 36bbbf1280Sopenharmony_ci__memset_arm: 37bbbf1280Sopenharmony_ci @ r0 = address 38bbbf1280Sopenharmony_ci @ r1 = character 39bbbf1280Sopenharmony_ci @ r2 = count 40bbbf1280Sopenharmony_ci @ returns original address in r0 41bbbf1280Sopenharmony_ci 42bbbf1280Sopenharmony_ci mov r3, r0 @ Leave r0 alone 43bbbf1280Sopenharmony_ci cbz r2, 10f @ Exit if 0 length 44bbbf1280Sopenharmony_ci 45bbbf1280Sopenharmony_ci tst r0, #7 46bbbf1280Sopenharmony_ci beq 2f @ Already aligned 47bbbf1280Sopenharmony_ci 48bbbf1280Sopenharmony_ci @ Ok, so we're misaligned here 49bbbf1280Sopenharmony_ci1: 50bbbf1280Sopenharmony_ci strb r1, [r3], #1 51bbbf1280Sopenharmony_ci subs r2,r2,#1 52bbbf1280Sopenharmony_ci tst r3, #7 53bbbf1280Sopenharmony_ci cbz r2, 10f @ Exit if we hit the end 54bbbf1280Sopenharmony_ci bne 1b @ go round again if still misaligned 55bbbf1280Sopenharmony_ci 56bbbf1280Sopenharmony_ci2: 57bbbf1280Sopenharmony_ci @ OK, so we're aligned 58bbbf1280Sopenharmony_ci push {r4,r5,r6,r7} 59bbbf1280Sopenharmony_ci bics r4, r2, #15 @ if less than 16 bytes then need to finish it off 60bbbf1280Sopenharmony_ci beq 5f 61bbbf1280Sopenharmony_ci 62bbbf1280Sopenharmony_ci3: 63bbbf1280Sopenharmony_ci @ POSIX says that ch is cast to an unsigned char. A uxtb is one 64bbbf1280Sopenharmony_ci @ byte and takes two cycles, where an AND is four bytes but one 65bbbf1280Sopenharmony_ci @ cycle. 66bbbf1280Sopenharmony_ci and r1, #0xFF 67bbbf1280Sopenharmony_ci orr r1, r1, r1, lsl#8 @ Same character into all bytes 68bbbf1280Sopenharmony_ci orr r1, r1, r1, lsl#16 69bbbf1280Sopenharmony_ci mov r5,r1 70bbbf1280Sopenharmony_ci mov r6,r1 71bbbf1280Sopenharmony_ci mov r7,r1 72bbbf1280Sopenharmony_ci 73bbbf1280Sopenharmony_ci4: 74bbbf1280Sopenharmony_ci subs r4,r4,#16 75bbbf1280Sopenharmony_ci stmia r3!,{r1,r5,r6,r7} 76bbbf1280Sopenharmony_ci bne 4b 77bbbf1280Sopenharmony_ci and r2,r2,#15 78bbbf1280Sopenharmony_ci 79bbbf1280Sopenharmony_ci @ At this point we're still aligned and we have upto align-1 bytes left to right 80bbbf1280Sopenharmony_ci @ we can avoid some of the byte-at-a time now by testing for some big chunks 81bbbf1280Sopenharmony_ci tst r2,#8 82bbbf1280Sopenharmony_ci itt ne 83bbbf1280Sopenharmony_ci subne r2,r2,#8 84bbbf1280Sopenharmony_ci stmiane r3!,{r1,r5} 85bbbf1280Sopenharmony_ci 86bbbf1280Sopenharmony_ci5: 87bbbf1280Sopenharmony_ci pop {r4,r5,r6,r7} 88bbbf1280Sopenharmony_ci cbz r2, 10f 89bbbf1280Sopenharmony_ci 90bbbf1280Sopenharmony_ci @ Got to do any last < alignment bytes 91bbbf1280Sopenharmony_ci6: 92bbbf1280Sopenharmony_ci subs r2,r2,#1 93bbbf1280Sopenharmony_ci strb r1,[r3],#1 94bbbf1280Sopenharmony_ci bne 6b 95bbbf1280Sopenharmony_ci 96bbbf1280Sopenharmony_ci10: 97bbbf1280Sopenharmony_ci bx lr @ goodbye 98bbbf1280Sopenharmony_ci .size __memset_arm, . - __memset_arm 99