memset.S 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
  3. #include <linux/linkage.h>
  4. #include "sysdep.h"
  5. .weak memset
  6. ENTRY(__memset)
  7. ENTRY(memset)
  8. /* Test if len less than 4 bytes. */
  9. mov r12, r0
  10. cmplti r2, 8
  11. bt .L_set_by_byte
  12. andi r13, r0, 3
  13. movi r19, 4
  14. /* Test if dest is not 4 bytes aligned. */
  15. bnez r13, .L_dest_not_aligned
  16. /* Hardware can handle unaligned access directly. */
  17. .L_dest_aligned:
  18. zextb r3, r1
  19. lsli r1, 8
  20. or r1, r3
  21. lsli r3, r1, 16
  22. or r3, r1
  23. /* If dest is aligned, then copy. */
  24. zext r18, r2, 31, 4
  25. /* Test if len less than 16 bytes. */
  26. bez r18, .L_len_less_16bytes
  27. LABLE_ALIGN
  28. .L_len_larger_16bytes:
  29. stw r3, (r0, 0)
  30. stw r3, (r0, 4)
  31. stw r3, (r0, 8)
  32. stw r3, (r0, 12)
  33. PRE_BNEZAD (r18)
  34. addi r0, 16
  35. BNEZAD (r18, .L_len_larger_16bytes)
  36. .L_len_less_16bytes:
  37. zext r18, r2, 3, 2
  38. andi r2, 3
  39. bez r18, .L_set_by_byte
  40. .L_len_less_16bytes_loop:
  41. stw r3, (r0, 0)
  42. PRE_BNEZAD (r18)
  43. addi r0, 4
  44. BNEZAD (r18, .L_len_less_16bytes_loop)
  45. /* Test if len less than 4 bytes. */
  46. .L_set_by_byte:
  47. zext r18, r2, 2, 0
  48. bez r18, .L_return
  49. .L_set_by_byte_loop:
  50. stb r1, (r0, 0)
  51. PRE_BNEZAD (r18)
  52. addi r0, 1
  53. BNEZAD (r18, .L_set_by_byte_loop)
  54. .L_return:
  55. mov r0, r12
  56. rts
  57. /* If dest is not aligned, just set some bytes makes the dest
  58. align. */
  59. .L_dest_not_aligned:
  60. sub r13, r19, r13
  61. sub r2, r13
  62. .L_dest_not_aligned_loop:
  63. /* Makes the dest align. */
  64. stb r1, (r0, 0)
  65. PRE_BNEZAD (r13)
  66. addi r0, 1
  67. BNEZAD (r13, .L_dest_not_aligned_loop)
  68. cmplti r2, 8
  69. bt .L_set_by_byte
  70. /* Check whether the src is aligned. */
  71. jbr .L_dest_aligned
  72. ENDPROC(memset)
  73. ENDPROC(__memset)