copy_in_user.S 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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,z) \
  9. 98: x,y; \
  10. .section __ex_table,"a";\
  11. .align 4; \
  12. .word 98b, z; \
  13. .text; \
  14. .align 4;
  15. #define EX_O4(x,y) EX(x,y,__retl_o4_plus_8)
  16. #define EX_O2_4(x,y) EX(x,y,__retl_o2_plus_4)
  17. #define EX_O2_1(x,y) EX(x,y,__retl_o2_plus_1)
  18. .register %g2,#scratch
  19. .register %g3,#scratch
  20. .text
  21. __retl_o4_plus_8:
  22. add %o4, %o2, %o4
  23. retl
  24. add %o4, 8, %o0
  25. __retl_o2_plus_4:
  26. retl
  27. add %o2, 4, %o0
  28. __retl_o2_plus_1:
  29. retl
  30. add %o2, 1, %o0
  31. .align 32
  32. /* Don't try to get too fancy here, just nice and
  33. * simple. This is predominantly used for well aligned
  34. * small copies in the compat layer. It is also used
  35. * to copy register windows around during thread cloning.
  36. */
  37. ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */
  38. cmp %o2, 0
  39. be,pn %XCC, 85f
  40. or %o0, %o1, %o3
  41. cmp %o2, 16
  42. bleu,a,pn %XCC, 80f
  43. or %o3, %o2, %o3
  44. /* 16 < len <= 64 */
  45. andcc %o3, 0x7, %g0
  46. bne,pn %XCC, 90f
  47. nop
  48. andn %o2, 0x7, %o4
  49. and %o2, 0x7, %o2
  50. 1: subcc %o4, 0x8, %o4
  51. EX_O4(ldxa [%o1] %asi, %o5)
  52. EX_O4(stxa %o5, [%o0] %asi)
  53. add %o1, 0x8, %o1
  54. bgu,pt %XCC, 1b
  55. add %o0, 0x8, %o0
  56. andcc %o2, 0x4, %g0
  57. be,pt %XCC, 1f
  58. nop
  59. sub %o2, 0x4, %o2
  60. EX_O2_4(lduwa [%o1] %asi, %o5)
  61. EX_O2_4(stwa %o5, [%o0] %asi)
  62. add %o1, 0x4, %o1
  63. add %o0, 0x4, %o0
  64. 1: cmp %o2, 0
  65. be,pt %XCC, 85f
  66. nop
  67. ba,pt %xcc, 90f
  68. nop
  69. 80: /* 0 < len <= 16 */
  70. andcc %o3, 0x3, %g0
  71. bne,pn %XCC, 90f
  72. nop
  73. 82:
  74. subcc %o2, 4, %o2
  75. EX_O2_4(lduwa [%o1] %asi, %g1)
  76. EX_O2_4(stwa %g1, [%o0] %asi)
  77. add %o1, 4, %o1
  78. bgu,pt %XCC, 82b
  79. add %o0, 4, %o0
  80. 85: retl
  81. clr %o0
  82. .align 32
  83. 90:
  84. subcc %o2, 1, %o2
  85. EX_O2_1(lduba [%o1] %asi, %g1)
  86. EX_O2_1(stba %g1, [%o0] %asi)
  87. add %o1, 1, %o1
  88. bgu,pt %XCC, 90b
  89. add %o0, 1, %o0
  90. retl
  91. clr %o0
  92. ENDPROC(___copy_in_user)