mem.S 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * String handling functions.
  4. *
  5. * Copyright IBM Corp. 2012
  6. */
  7. #include <linux/linkage.h>
  8. #include <asm/export.h>
  9. #include <asm/nospec-insn.h>
  10. GEN_BR_THUNK %r14
  11. /*
  12. * void *memmove(void *dest, const void *src, size_t n)
  13. */
  14. ENTRY(memmove)
  15. ltgr %r4,%r4
  16. lgr %r1,%r2
  17. jz .Lmemmove_exit
  18. aghi %r4,-1
  19. clgr %r2,%r3
  20. jnh .Lmemmove_forward
  21. la %r5,1(%r4,%r3)
  22. clgr %r2,%r5
  23. jl .Lmemmove_reverse
  24. .Lmemmove_forward:
  25. srlg %r0,%r4,8
  26. ltgr %r0,%r0
  27. jz .Lmemmove_forward_remainder
  28. .Lmemmove_forward_loop:
  29. mvc 0(256,%r1),0(%r3)
  30. la %r1,256(%r1)
  31. la %r3,256(%r3)
  32. brctg %r0,.Lmemmove_forward_loop
  33. .Lmemmove_forward_remainder:
  34. larl %r5,.Lmemmove_mvc
  35. ex %r4,0(%r5)
  36. .Lmemmove_exit:
  37. BR_EX %r14
  38. .Lmemmove_reverse:
  39. ic %r0,0(%r4,%r3)
  40. stc %r0,0(%r4,%r1)
  41. brctg %r4,.Lmemmove_reverse
  42. ic %r0,0(%r4,%r3)
  43. stc %r0,0(%r4,%r1)
  44. BR_EX %r14
  45. .Lmemmove_mvc:
  46. mvc 0(1,%r1),0(%r3)
  47. EXPORT_SYMBOL(memmove)
  48. /*
  49. * memset implementation
  50. *
  51. * This code corresponds to the C construct below. We do distinguish
  52. * between clearing (c == 0) and setting a memory array (c != 0) simply
  53. * because nearly all memset invocations in the kernel clear memory and
  54. * the xc instruction is preferred in such cases.
  55. *
  56. * void *memset(void *s, int c, size_t n)
  57. * {
  58. * if (likely(c == 0))
  59. * return __builtin_memset(s, 0, n);
  60. * return __builtin_memset(s, c, n);
  61. * }
  62. */
  63. ENTRY(memset)
  64. ltgr %r4,%r4
  65. jz .Lmemset_exit
  66. ltgr %r3,%r3
  67. jnz .Lmemset_fill
  68. aghi %r4,-1
  69. srlg %r3,%r4,8
  70. ltgr %r3,%r3
  71. lgr %r1,%r2
  72. jz .Lmemset_clear_remainder
  73. .Lmemset_clear_loop:
  74. xc 0(256,%r1),0(%r1)
  75. la %r1,256(%r1)
  76. brctg %r3,.Lmemset_clear_loop
  77. .Lmemset_clear_remainder:
  78. larl %r3,.Lmemset_xc
  79. ex %r4,0(%r3)
  80. .Lmemset_exit:
  81. BR_EX %r14
  82. .Lmemset_fill:
  83. cghi %r4,1
  84. lgr %r1,%r2
  85. je .Lmemset_fill_exit
  86. aghi %r4,-2
  87. srlg %r5,%r4,8
  88. ltgr %r5,%r5
  89. jz .Lmemset_fill_remainder
  90. .Lmemset_fill_loop:
  91. stc %r3,0(%r1)
  92. mvc 1(255,%r1),0(%r1)
  93. la %r1,256(%r1)
  94. brctg %r5,.Lmemset_fill_loop
  95. .Lmemset_fill_remainder:
  96. stc %r3,0(%r1)
  97. larl %r5,.Lmemset_mvc
  98. ex %r4,0(%r5)
  99. BR_EX %r14
  100. .Lmemset_fill_exit:
  101. stc %r3,0(%r1)
  102. BR_EX %r14
  103. .Lmemset_xc:
  104. xc 0(1,%r1),0(%r1)
  105. .Lmemset_mvc:
  106. mvc 1(1,%r1),0(%r1)
  107. EXPORT_SYMBOL(memset)
  108. /*
  109. * memcpy implementation
  110. *
  111. * void *memcpy(void *dest, const void *src, size_t n)
  112. */
  113. ENTRY(memcpy)
  114. ltgr %r4,%r4
  115. jz .Lmemcpy_exit
  116. aghi %r4,-1
  117. srlg %r5,%r4,8
  118. ltgr %r5,%r5
  119. lgr %r1,%r2
  120. jnz .Lmemcpy_loop
  121. .Lmemcpy_remainder:
  122. larl %r5,.Lmemcpy_mvc
  123. ex %r4,0(%r5)
  124. .Lmemcpy_exit:
  125. BR_EX %r14
  126. .Lmemcpy_loop:
  127. mvc 0(256,%r1),0(%r3)
  128. la %r1,256(%r1)
  129. la %r3,256(%r3)
  130. brctg %r5,.Lmemcpy_loop
  131. j .Lmemcpy_remainder
  132. .Lmemcpy_mvc:
  133. mvc 0(1,%r1),0(%r3)
  134. EXPORT_SYMBOL(memcpy)
  135. /*
  136. * __memset16/32/64
  137. *
  138. * void *__memset16(uint16_t *s, uint16_t v, size_t count)
  139. * void *__memset32(uint32_t *s, uint32_t v, size_t count)
  140. * void *__memset64(uint64_t *s, uint64_t v, size_t count)
  141. */
  142. .macro __MEMSET bits,bytes,insn
  143. ENTRY(__memset\bits)
  144. ltgr %r4,%r4
  145. jz .L__memset_exit\bits
  146. cghi %r4,\bytes
  147. je .L__memset_store\bits
  148. aghi %r4,-(\bytes+1)
  149. srlg %r5,%r4,8
  150. ltgr %r5,%r5
  151. lgr %r1,%r2
  152. jz .L__memset_remainder\bits
  153. .L__memset_loop\bits:
  154. \insn %r3,0(%r1)
  155. mvc \bytes(256-\bytes,%r1),0(%r1)
  156. la %r1,256(%r1)
  157. brctg %r5,.L__memset_loop\bits
  158. .L__memset_remainder\bits:
  159. \insn %r3,0(%r1)
  160. larl %r5,.L__memset_mvc\bits
  161. ex %r4,0(%r5)
  162. BR_EX %r14
  163. .L__memset_store\bits:
  164. \insn %r3,0(%r2)
  165. .L__memset_exit\bits:
  166. BR_EX %r14
  167. .L__memset_mvc\bits:
  168. mvc \bytes(1,%r1),0(%r1)
  169. .endm
  170. __MEMSET 16,2,sth
  171. EXPORT_SYMBOL(__memset16)
  172. __MEMSET 32,4,st
  173. EXPORT_SYMBOL(__memset32)
  174. __MEMSET 64,8,stg
  175. EXPORT_SYMBOL(__memset64)