|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- /*
- * Copyright (c) 2014 Travis Geiselbrecht
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- //#include <asm.h>
- //#include <arch/arm/cores.h>
- #if defined (__OPTIMIZE_SIZE__)
- #if defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
- .global memset
- .text
- .syntax unified
- .thumb
- .align 2
-
- /* void *memset(void *s, int c, size_t n); */
- .type memset, %function
- .thumb_func
- memset:
- //FUNCTION(memset)
- // save the original pointer
- push { r0, lr }
-
- // check for zero length
- cbz r2, .L_done
-
- // short memsets aren't worth optimizing and make sure we have
- // enough headroom to try to do dwordwise move optimization
- cmp r2, #16
- blt .L_bytewise
-
- // see how many bytes we need to move to align to dword boundaries
- and r3, r0, #7
- cbz r3, .L_prepare_dwordwise
- rsb r3, #8
- subs r2, r3
-
- .L_bytewise_align:
- // bytewise to align memset
- subs r3, r3, #1
- strb r1, [r0], #1
- bgt .L_bytewise_align
-
- .L_prepare_dwordwise:
- // fill a pair of 32 bit registers with the 8 bit value
- uxtb r1, r1
- orr r1, r1, r1, lsl #8
- orr r1, r1, r1, lsl #16
- mov r12, r1
-
- // load the number of dwords left
- lsrs r3, r2, #3
-
- .L_dwordwise:
- // dwordwise memset
-
- subs r3, r3, #1
- strd r1, r12, [r0], #8
- bgt .L_dwordwise
-
- // remaining bytes
- ands r2, #7
- beq .L_done
-
- .L_bytewise:
- // bytewise memset
- subs r2, r2, #1
- strb r1, [r0], #1
- bgt .L_bytewise
-
- .L_done:
- // restore the base pointer as return value
- pop { r0, pc }
-
- #endif
- #endif
|