una_asm_32.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /* una_asm.S: Kernel unaligned trap assembler helpers.
  3. *
  4. * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net)
  5. * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  6. */
  7. #include <linux/errno.h>
  8. .text
  9. retl_efault:
  10. retl
  11. mov -EFAULT, %o0
  12. /* int __do_int_store(unsigned long *dst_addr, int size,
  13. * unsigned long *src_val)
  14. *
  15. * %o0 = dest_addr
  16. * %o1 = size
  17. * %o2 = src_val
  18. *
  19. * Return '0' on success, -EFAULT on failure.
  20. */
  21. .globl __do_int_store
  22. __do_int_store:
  23. ld [%o2], %g1
  24. cmp %o1, 2
  25. be 2f
  26. cmp %o1, 4
  27. be 1f
  28. srl %g1, 24, %g2
  29. srl %g1, 16, %g7
  30. 4: stb %g2, [%o0]
  31. srl %g1, 8, %g2
  32. 5: stb %g7, [%o0 + 1]
  33. ld [%o2 + 4], %g7
  34. 6: stb %g2, [%o0 + 2]
  35. srl %g7, 24, %g2
  36. 7: stb %g1, [%o0 + 3]
  37. srl %g7, 16, %g1
  38. 8: stb %g2, [%o0 + 4]
  39. srl %g7, 8, %g2
  40. 9: stb %g1, [%o0 + 5]
  41. 10: stb %g2, [%o0 + 6]
  42. b 0f
  43. 11: stb %g7, [%o0 + 7]
  44. 1: srl %g1, 16, %g7
  45. 12: stb %g2, [%o0]
  46. srl %g1, 8, %g2
  47. 13: stb %g7, [%o0 + 1]
  48. 14: stb %g2, [%o0 + 2]
  49. b 0f
  50. 15: stb %g1, [%o0 + 3]
  51. 2: srl %g1, 8, %g2
  52. 16: stb %g2, [%o0]
  53. 17: stb %g1, [%o0 + 1]
  54. 0: retl
  55. mov 0, %o0
  56. .section __ex_table,#alloc
  57. .word 4b, retl_efault
  58. .word 5b, retl_efault
  59. .word 6b, retl_efault
  60. .word 7b, retl_efault
  61. .word 8b, retl_efault
  62. .word 9b, retl_efault
  63. .word 10b, retl_efault
  64. .word 11b, retl_efault
  65. .word 12b, retl_efault
  66. .word 13b, retl_efault
  67. .word 14b, retl_efault
  68. .word 15b, retl_efault
  69. .word 16b, retl_efault
  70. .word 17b, retl_efault
  71. .previous
  72. /* int do_int_load(unsigned long *dest_reg, int size,
  73. * unsigned long *saddr, int is_signed)
  74. *
  75. * %o0 = dest_reg
  76. * %o1 = size
  77. * %o2 = saddr
  78. * %o3 = is_signed
  79. *
  80. * Return '0' on success, -EFAULT on failure.
  81. */
  82. .globl do_int_load
  83. do_int_load:
  84. cmp %o1, 8
  85. be 9f
  86. cmp %o1, 4
  87. be 6f
  88. 4: ldub [%o2], %g1
  89. 5: ldub [%o2 + 1], %g2
  90. sll %g1, 8, %g1
  91. tst %o3
  92. be 3f
  93. or %g1, %g2, %g1
  94. sll %g1, 16, %g1
  95. sra %g1, 16, %g1
  96. 3: b 0f
  97. st %g1, [%o0]
  98. 6: ldub [%o2 + 1], %g2
  99. sll %g1, 24, %g1
  100. 7: ldub [%o2 + 2], %g7
  101. sll %g2, 16, %g2
  102. 8: ldub [%o2 + 3], %g3
  103. sll %g7, 8, %g7
  104. or %g3, %g2, %g3
  105. or %g7, %g3, %g7
  106. or %g1, %g7, %g1
  107. b 0f
  108. st %g1, [%o0]
  109. 9: ldub [%o2], %g1
  110. 10: ldub [%o2 + 1], %g2
  111. sll %g1, 24, %g1
  112. 11: ldub [%o2 + 2], %g7
  113. sll %g2, 16, %g2
  114. 12: ldub [%o2 + 3], %g3
  115. sll %g7, 8, %g7
  116. or %g1, %g2, %g1
  117. or %g7, %g3, %g7
  118. or %g1, %g7, %g7
  119. 13: ldub [%o2 + 4], %g1
  120. st %g7, [%o0]
  121. 14: ldub [%o2 + 5], %g2
  122. sll %g1, 24, %g1
  123. 15: ldub [%o2 + 6], %g7
  124. sll %g2, 16, %g2
  125. 16: ldub [%o2 + 7], %g3
  126. sll %g7, 8, %g7
  127. or %g1, %g2, %g1
  128. or %g7, %g3, %g7
  129. or %g1, %g7, %g7
  130. st %g7, [%o0 + 4]
  131. 0: retl
  132. mov 0, %o0
  133. .section __ex_table,#alloc
  134. .word 4b, retl_efault
  135. .word 5b, retl_efault
  136. .word 6b, retl_efault
  137. .word 7b, retl_efault
  138. .word 8b, retl_efault
  139. .word 9b, retl_efault
  140. .word 10b, retl_efault
  141. .word 11b, retl_efault
  142. .word 12b, retl_efault
  143. .word 13b, retl_efault
  144. .word 14b, retl_efault
  145. .word 15b, retl_efault
  146. .word 16b, retl_efault
  147. .previous