strncpy_from_user_64.S 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * strncpy_from_user.S: Sparc64 strncpy from userspace.
  3. *
  4. * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
  5. */
  6. #include <asm/asi.h>
  7. #include <asm/errno.h>
  8. .data
  9. .align 8
  10. 0: .xword 0x0101010101010101
  11. .text
  12. .align 32
  13. /* Must return:
  14. *
  15. * -EFAULT for an exception
  16. * count if we hit the buffer limit
  17. * bytes copied if we hit a null byte
  18. * (without the null byte)
  19. *
  20. * This implementation assumes:
  21. * %o1 is 8 aligned => !(%o2 & 7)
  22. * %o0 is 8 aligned (if not, it will be slooooow, but will work)
  23. *
  24. * This is optimized for the common case:
  25. * in my stats, 90% of src are 8 aligned (even on sparc32)
  26. * and average length is 18 or so.
  27. */
  28. .globl __strncpy_from_user
  29. .type __strncpy_from_user,#function
  30. __strncpy_from_user:
  31. /* %o0=dest, %o1=src, %o2=count */
  32. andcc %o1, 7, %g0 ! IEU1 Group
  33. bne,pn %icc, 30f ! CTI
  34. add %o0, %o2, %g3 ! IEU0
  35. 60: ldxa [%o1] %asi, %g1 ! Load Group
  36. brlez,pn %o2, 10f ! CTI
  37. mov %o0, %o3 ! IEU0
  38. 50: sethi %hi(0b), %o4 ! IEU0 Group
  39. ldx [%o4 + %lo(0b)], %o4 ! Load
  40. sllx %o4, 7, %o5 ! IEU1 Group
  41. 1: sub %g1, %o4, %g2 ! IEU0 Group
  42. stx %g1, [%o0] ! Store
  43. add %o0, 8, %o0 ! IEU1
  44. andcc %g2, %o5, %g0 ! IEU1 Group
  45. bne,pn %xcc, 5f ! CTI
  46. add %o1, 8, %o1 ! IEU0
  47. cmp %o0, %g3 ! IEU1 Group
  48. bl,a,pt %xcc, 1b ! CTI
  49. 61: ldxa [%o1] %asi, %g1 ! Load
  50. 10: retl ! CTI Group
  51. mov %o2, %o0 ! IEU0
  52. 5: srlx %g2, 32, %g7 ! IEU0 Group
  53. sethi %hi(0xff00), %o4 ! IEU1
  54. andcc %g7, %o5, %g0 ! IEU1 Group
  55. be,pn %icc, 2f ! CTI
  56. or %o4, %lo(0xff00), %o4 ! IEU0
  57. srlx %g1, 48, %g7 ! IEU0 Group
  58. andcc %g7, %o4, %g0 ! IEU1 Group
  59. be,pn %icc, 50f ! CTI
  60. andcc %g7, 0xff, %g0 ! IEU1 Group
  61. be,pn %icc, 51f ! CTI
  62. srlx %g1, 32, %g7 ! IEU0
  63. andcc %g7, %o4, %g0 ! IEU1 Group
  64. be,pn %icc, 52f ! CTI
  65. andcc %g7, 0xff, %g0 ! IEU1 Group
  66. be,pn %icc, 53f ! CTI
  67. 2: andcc %g2, %o5, %g0 ! IEU1 Group
  68. be,pn %icc, 2f ! CTI
  69. srl %g1, 16, %g7 ! IEU0
  70. andcc %g7, %o4, %g0 ! IEU1 Group
  71. be,pn %icc, 54f ! CTI
  72. andcc %g7, 0xff, %g0 ! IEU1 Group
  73. be,pn %icc, 55f ! CTI
  74. andcc %g1, %o4, %g0 ! IEU1 Group
  75. be,pn %icc, 56f ! CTI
  76. andcc %g1, 0xff, %g0 ! IEU1 Group
  77. be,a,pn %icc, 57f ! CTI
  78. sub %o0, %o3, %o0 ! IEU0
  79. 2: cmp %o0, %g3 ! IEU1 Group
  80. bl,a,pt %xcc, 50b ! CTI
  81. 62: ldxa [%o1] %asi, %g1 ! Load
  82. retl ! CTI Group
  83. mov %o2, %o0 ! IEU0
  84. 50: sub %o0, %o3, %o0
  85. retl
  86. sub %o0, 8, %o0
  87. 51: sub %o0, %o3, %o0
  88. retl
  89. sub %o0, 7, %o0
  90. 52: sub %o0, %o3, %o0
  91. retl
  92. sub %o0, 6, %o0
  93. 53: sub %o0, %o3, %o0
  94. retl
  95. sub %o0, 5, %o0
  96. 54: sub %o0, %o3, %o0
  97. retl
  98. sub %o0, 4, %o0
  99. 55: sub %o0, %o3, %o0
  100. retl
  101. sub %o0, 3, %o0
  102. 56: sub %o0, %o3, %o0
  103. retl
  104. sub %o0, 2, %o0
  105. 57: retl
  106. sub %o0, 1, %o0
  107. 30: brlez,pn %o2, 3f
  108. sub %g0, %o2, %o3
  109. add %o0, %o2, %o0
  110. 63: lduba [%o1] %asi, %o4
  111. 1: add %o1, 1, %o1
  112. brz,pn %o4, 2f
  113. stb %o4, [%o0 + %o3]
  114. addcc %o3, 1, %o3
  115. bne,pt %xcc, 1b
  116. 64: lduba [%o1] %asi, %o4
  117. 3: retl
  118. mov %o2, %o0
  119. 2: retl
  120. add %o2, %o3, %o0
  121. .size __strncpy_from_user, .-__strncpy_from_user
  122. .section __ex_table,"a"
  123. .align 4
  124. .word 60b, __retl_efault
  125. .word 61b, __retl_efault
  126. .word 62b, __retl_efault
  127. .word 63b, __retl_efault
  128. .word 64b, __retl_efault
  129. .previous