strncpy_from_user_64.S 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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 <linux/linkage.h>
  7. #include <asm/asi.h>
  8. #include <asm/errno.h>
  9. .data
  10. .align 8
  11. 0: .xword 0x0101010101010101
  12. .text
  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. ENTRY(__strncpy_from_user)
  29. /* %o0=dest, %o1=src, %o2=count */
  30. andcc %o1, 7, %g0 ! IEU1 Group
  31. bne,pn %icc, 30f ! CTI
  32. add %o0, %o2, %g3 ! IEU0
  33. 60: ldxa [%o1] %asi, %g1 ! Load Group
  34. brlez,pn %o2, 10f ! CTI
  35. mov %o0, %o3 ! IEU0
  36. 50: sethi %hi(0b), %o4 ! IEU0 Group
  37. ldx [%o4 + %lo(0b)], %o4 ! Load
  38. sllx %o4, 7, %o5 ! IEU1 Group
  39. 1: sub %g1, %o4, %g2 ! IEU0 Group
  40. stx %g1, [%o0] ! Store
  41. add %o0, 8, %o0 ! IEU1
  42. andcc %g2, %o5, %g0 ! IEU1 Group
  43. bne,pn %xcc, 5f ! CTI
  44. add %o1, 8, %o1 ! IEU0
  45. cmp %o0, %g3 ! IEU1 Group
  46. bl,a,pt %xcc, 1b ! CTI
  47. 61: ldxa [%o1] %asi, %g1 ! Load
  48. 10: retl ! CTI Group
  49. mov %o2, %o0 ! IEU0
  50. 5: srlx %g2, 32, %g7 ! IEU0 Group
  51. sethi %hi(0xff00), %o4 ! IEU1
  52. andcc %g7, %o5, %g0 ! IEU1 Group
  53. be,pn %icc, 2f ! CTI
  54. or %o4, %lo(0xff00), %o4 ! IEU0
  55. srlx %g1, 48, %g7 ! IEU0 Group
  56. andcc %g7, %o4, %g0 ! IEU1 Group
  57. be,pn %icc, 50f ! CTI
  58. andcc %g7, 0xff, %g0 ! IEU1 Group
  59. be,pn %icc, 51f ! CTI
  60. srlx %g1, 32, %g7 ! IEU0
  61. andcc %g7, %o4, %g0 ! IEU1 Group
  62. be,pn %icc, 52f ! CTI
  63. andcc %g7, 0xff, %g0 ! IEU1 Group
  64. be,pn %icc, 53f ! CTI
  65. 2: andcc %g2, %o5, %g0 ! IEU1 Group
  66. be,pn %icc, 2f ! CTI
  67. srl %g1, 16, %g7 ! IEU0
  68. andcc %g7, %o4, %g0 ! IEU1 Group
  69. be,pn %icc, 54f ! CTI
  70. andcc %g7, 0xff, %g0 ! IEU1 Group
  71. be,pn %icc, 55f ! CTI
  72. andcc %g1, %o4, %g0 ! IEU1 Group
  73. be,pn %icc, 56f ! CTI
  74. andcc %g1, 0xff, %g0 ! IEU1 Group
  75. be,a,pn %icc, 57f ! CTI
  76. sub %o0, %o3, %o0 ! IEU0
  77. 2: cmp %o0, %g3 ! IEU1 Group
  78. bl,a,pt %xcc, 50b ! CTI
  79. 62: ldxa [%o1] %asi, %g1 ! Load
  80. retl ! CTI Group
  81. mov %o2, %o0 ! IEU0
  82. 50: sub %o0, %o3, %o0
  83. retl
  84. sub %o0, 8, %o0
  85. 51: sub %o0, %o3, %o0
  86. retl
  87. sub %o0, 7, %o0
  88. 52: sub %o0, %o3, %o0
  89. retl
  90. sub %o0, 6, %o0
  91. 53: sub %o0, %o3, %o0
  92. retl
  93. sub %o0, 5, %o0
  94. 54: sub %o0, %o3, %o0
  95. retl
  96. sub %o0, 4, %o0
  97. 55: sub %o0, %o3, %o0
  98. retl
  99. sub %o0, 3, %o0
  100. 56: sub %o0, %o3, %o0
  101. retl
  102. sub %o0, 2, %o0
  103. 57: retl
  104. sub %o0, 1, %o0
  105. 30: brlez,pn %o2, 3f
  106. sub %g0, %o2, %o3
  107. add %o0, %o2, %o0
  108. 63: lduba [%o1] %asi, %o4
  109. 1: add %o1, 1, %o1
  110. brz,pn %o4, 2f
  111. stb %o4, [%o0 + %o3]
  112. addcc %o3, 1, %o3
  113. bne,pt %xcc, 1b
  114. 64: lduba [%o1] %asi, %o4
  115. 3: retl
  116. mov %o2, %o0
  117. 2: retl
  118. add %o2, %o3, %o0
  119. ENDPROC(__strncpy_from_user)
  120. .section __ex_table,"a"
  121. .align 4
  122. .word 60b, __retl_efault
  123. .word 61b, __retl_efault
  124. .word 62b, __retl_efault
  125. .word 63b, __retl_efault
  126. .word 64b, __retl_efault
  127. .previous