You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright (c) 2014 Travis Geiselbrecht
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining
  5. * a copy of this software and associated documentation files
  6. * (the "Software"), to deal in the Software without restriction,
  7. * including without limitation the rights to use, copy, modify, merge,
  8. * publish, distribute, sublicense, and/or sell copies of the Software,
  9. * and to permit persons to whom the Software is furnished to do so,
  10. * subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be
  13. * included in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  19. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  20. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  21. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. //#include <asm.h>
  24. //#include <arch/arm/cores.h>
  25. #if defined (__OPTIMIZE_SIZE__)
  26. #if defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
  27. .global memset
  28. .text
  29. .syntax unified
  30. .thumb
  31. .align 2
  32. /* void *memset(void *s, int c, size_t n); */
  33. .type memset, %function
  34. .thumb_func
  35. memset:
  36. //FUNCTION(memset)
  37. // save the original pointer
  38. push { r0, lr }
  39. // check for zero length
  40. cbz r2, .L_done
  41. // short memsets aren't worth optimizing and make sure we have
  42. // enough headroom to try to do dwordwise move optimization
  43. cmp r2, #16
  44. blt .L_bytewise
  45. // see how many bytes we need to move to align to dword boundaries
  46. and r3, r0, #7
  47. cbz r3, .L_prepare_dwordwise
  48. rsb r3, #8
  49. subs r2, r3
  50. .L_bytewise_align:
  51. // bytewise to align memset
  52. subs r3, r3, #1
  53. strb r1, [r0], #1
  54. bgt .L_bytewise_align
  55. .L_prepare_dwordwise:
  56. // fill a pair of 32 bit registers with the 8 bit value
  57. uxtb r1, r1
  58. orr r1, r1, r1, lsl #8
  59. orr r1, r1, r1, lsl #16
  60. mov r12, r1
  61. // load the number of dwords left
  62. lsrs r3, r2, #3
  63. .L_dwordwise:
  64. // dwordwise memset
  65. subs r3, r3, #1
  66. strd r1, r12, [r0], #8
  67. bgt .L_dwordwise
  68. // remaining bytes
  69. ands r2, #7
  70. beq .L_done
  71. .L_bytewise:
  72. // bytewise memset
  73. subs r2, r2, #1
  74. strb r1, [r0], #1
  75. bgt .L_bytewise
  76. .L_done:
  77. // restore the base pointer as return value
  78. pop { r0, pc }
  79. #endif
  80. #endif