copy_in_user.S 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* copy_in_user.S: Copy from userspace to userspace.
  2. *
  3. * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
  4. */
  5. #include <linux/linkage.h>
  6. #include <asm/asi.h>
  7. #define XCC xcc
  8. #define EX(x,y) \
  9. 98: x,y; \
  10. .section __ex_table,"a";\
  11. .align 4; \
  12. .word 98b, __retl_one; \
  13. .text; \
  14. .align 4;
  15. .register %g2,#scratch
  16. .register %g3,#scratch
  17. .text
  18. .align 32
  19. /* Don't try to get too fancy here, just nice and
  20. * simple. This is predominantly used for well aligned
  21. * small copies in the compat layer. It is also used
  22. * to copy register windows around during thread cloning.
  23. */
  24. ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */
  25. cmp %o2, 0
  26. be,pn %XCC, 85f
  27. or %o0, %o1, %o3
  28. cmp %o2, 16
  29. bleu,a,pn %XCC, 80f
  30. or %o3, %o2, %o3
  31. /* 16 < len <= 64 */
  32. andcc %o3, 0x7, %g0
  33. bne,pn %XCC, 90f
  34. nop
  35. andn %o2, 0x7, %o4
  36. and %o2, 0x7, %o2
  37. 1: subcc %o4, 0x8, %o4
  38. EX(ldxa [%o1] %asi, %o5)
  39. EX(stxa %o5, [%o0] %asi)
  40. add %o1, 0x8, %o1
  41. bgu,pt %XCC, 1b
  42. add %o0, 0x8, %o0
  43. andcc %o2, 0x4, %g0
  44. be,pt %XCC, 1f
  45. nop
  46. sub %o2, 0x4, %o2
  47. EX(lduwa [%o1] %asi, %o5)
  48. EX(stwa %o5, [%o0] %asi)
  49. add %o1, 0x4, %o1
  50. add %o0, 0x4, %o0
  51. 1: cmp %o2, 0
  52. be,pt %XCC, 85f
  53. nop
  54. ba,pt %xcc, 90f
  55. nop
  56. 80: /* 0 < len <= 16 */
  57. andcc %o3, 0x3, %g0
  58. bne,pn %XCC, 90f
  59. nop
  60. 82:
  61. subcc %o2, 4, %o2
  62. EX(lduwa [%o1] %asi, %g1)
  63. EX(stwa %g1, [%o0] %asi)
  64. add %o1, 4, %o1
  65. bgu,pt %XCC, 82b
  66. add %o0, 4, %o0
  67. 85: retl
  68. clr %o0
  69. .align 32
  70. 90:
  71. subcc %o2, 1, %o2
  72. EX(lduba [%o1] %asi, %g1)
  73. EX(stba %g1, [%o0] %asi)
  74. add %o1, 1, %o1
  75. bgu,pt %XCC, 90b
  76. add %o0, 1, %o0
  77. retl
  78. clr %o0
  79. ENDPROC(___copy_in_user)