una_asm_32.S 2.9 KB

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